about summary refs log tree commit diff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/alpha/getdents.c6
-rw-r--r--sysdeps/unix/sysv/linux/alpha/getdents64.c1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/kernel_stat.h2
-rw-r--r--sysdeps/unix/sysv/linux/bits/stat.h15
-rw-r--r--sysdeps/unix/sysv/linux/bits/types.h2
-rw-r--r--sysdeps/unix/sysv/linux/fxstat64.c30
-rw-r--r--sysdeps/unix/sysv/linux/getdents.c25
-rw-r--r--sysdeps/unix/sysv/linux/getdents64.c3
-rw-r--r--sysdeps/unix/sysv/linux/getdirentries.c13
-rw-r--r--sysdeps/unix/sysv/linux/getdirentries64.c3
-rw-r--r--sysdeps/unix/sysv/linux/i386/Versions17
-rw-r--r--sysdeps/unix/sysv/linux/i386/alphasort64.c48
-rw-r--r--sysdeps/unix/sysv/linux/i386/getdents64.c43
-rw-r--r--sysdeps/unix/sysv/linux/i386/olddirent.h44
-rw-r--r--sysdeps/unix/sysv/linux/i386/readdir64.c44
-rw-r--r--sysdeps/unix/sysv/linux/i386/readdir64_r.c44
-rw-r--r--sysdeps/unix/sysv/linux/i386/scandir64.c47
-rw-r--r--sysdeps/unix/sysv/linux/i386/versionsort64.c48
-rw-r--r--sysdeps/unix/sysv/linux/ia64/getdents.c4
-rw-r--r--sysdeps/unix/sysv/linux/ia64/getdents64.c1
-rw-r--r--sysdeps/unix/sysv/linux/ia64/readdir.c8
-rw-r--r--sysdeps/unix/sysv/linux/ia64/readdir_r.c5
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h7
-rw-r--r--sysdeps/unix/sysv/linux/kernel_stat.h14
-rw-r--r--sysdeps/unix/sysv/linux/lxstat64.c36
-rw-r--r--sysdeps/unix/sysv/linux/mips/bits/types.h2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/Versions17
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/stat.h128
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/getdents64.c1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/kernel_stat.h16
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/readdir64.c1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/readdir64_r.c1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/scandir64.c1
-rw-r--r--sysdeps/unix/sysv/linux/readdir64.c103
-rw-r--r--sysdeps/unix/sysv/linux/readdir64_r.c110
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/stat.h131
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/types.h2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/Versions19
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h14
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/getdents.c4
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/getdents64.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h15
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/readdir_r.c5
-rw-r--r--sysdeps/unix/sysv/linux/xstat64.c39
-rw-r--r--sysdeps/unix/sysv/linux/xstatconv.c79
50 files changed, 921 insertions, 290 deletions
diff --git a/sysdeps/unix/sysv/linux/alpha/getdents.c b/sysdeps/unix/sysv/linux/alpha/getdents.c
new file mode 100644
index 0000000000..6deb87e2e4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/getdents.c
@@ -0,0 +1,6 @@
+#define DIRENT_SET_DP_INO(dp, value) \
+  do { (dp)->d_ino = (value); (dp)->__pad = 0; } while (0)
+#define __getdents64 __no___getdents64_decl
+#include <sysdeps/unix/sysv/linux/getdents.c>
+#undef __getdents64
+weak_alias(__getdents, __getdents64);
diff --git a/sysdeps/unix/sysv/linux/alpha/getdents64.c b/sysdeps/unix/sysv/linux/alpha/getdents64.c
new file mode 100644
index 0000000000..0df2c8f4c6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/getdents64.c
@@ -0,0 +1 @@
+/* getdents64 is in getdents.c */
diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
index 2633b42525..75540c0a6d 100644
--- a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h
@@ -38,6 +38,4 @@ struct glibc2_stat
     unsigned int st_gen;
   };
 
-extern int __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf);
-
 #define XSTAT_IS_XSTAT64 1
diff --git a/sysdeps/unix/sysv/linux/bits/stat.h b/sysdeps/unix/sysv/linux/bits/stat.h
index d694738033..d432fc858e 100644
--- a/sysdeps/unix/sysv/linux/bits/stat.h
+++ b/sysdeps/unix/sysv/linux/bits/stat.h
@@ -40,7 +40,7 @@ struct stat
 #ifndef __USE_FILE_OFFSET64
     __ino_t st_ino;			/* File serial number.	*/
 #else
-    __ino64_t st_ino;			/* File serial number.	*/
+    __ino_t __st_ino;			/* 32bit file serial number.	*/
 #endif
     __mode_t st_mode;			/* File mode.  */
     __nlink_t st_nlink;			/* Link count.  */
@@ -66,23 +66,27 @@ struct stat
     unsigned long int __unused2;
     __time_t st_ctime;			/* Time of last status change.  */
     unsigned long int __unused3;
+#ifndef __USE_FILE_OFFSET64
     unsigned long int __unused4;
     unsigned long int __unused5;
+#else
+    __ino64_t st_ino;			/* File serial number.	*/
+#endif
   };
 
 #ifdef __USE_LARGEFILE64
 struct stat64
   {
     __dev_t st_dev;			/* Device.  */
-    unsigned short int __pad1;
+    unsigned int __pad1;
 
-    __ino64_t st_ino;			/* File serial number.	*/
+    __ino_t __st_ino;			/* 32bit file serial number.	*/
     __mode_t st_mode;			/* File mode.  */
     __nlink_t st_nlink;			/* Link count.  */
     __uid_t st_uid;			/* User ID of the file's owner.	*/
     __gid_t st_gid;			/* Group ID of the file's group.*/
     __dev_t st_rdev;			/* Device number, if device.  */
-    unsigned short int __pad2;
+    unsigned int __pad2;
     __off64_t st_size;			/* Size of file, in bytes.  */
     __blksize_t st_blksize;		/* Optimal block size for I/O.  */
 
@@ -93,8 +97,7 @@ struct stat64
     unsigned long int __unused2;
     __time_t st_ctime;			/* Time of last status change.  */
     unsigned long int __unused3;
-    unsigned long int __unused4;
-    unsigned long int __unused5;
+    __ino64_t st_ino;			/* File serial number.		*/
   };
 #endif
 
diff --git a/sysdeps/unix/sysv/linux/bits/types.h b/sysdeps/unix/sysv/linux/bits/types.h
index f9bf8394da..b5576357ae 100644
--- a/sysdeps/unix/sysv/linux/bits/types.h
+++ b/sysdeps/unix/sysv/linux/bits/types.h
@@ -137,7 +137,7 @@ typedef __u_long __fsfilcnt_t;
 typedef __u_quad_t __fsfilcnt64_t;
 
 /* Type of file serial numbers.  */
-typedef __u_long __ino64_t;
+typedef __u_quad_t __ino64_t;
 
 /* Type of file sizes and offsets.  */
 typedef __loff_t __off64_t;
diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
index 3cd21d4fc4..2140661ff3 100644
--- a/sysdeps/unix/sysv/linux/fxstat64.c
+++ b/sysdeps/unix/sysv/linux/fxstat64.c
@@ -43,13 +43,20 @@ extern int __have_no_stat64;
 #endif
 
 /* Get information about the file FD in BUF.  */
+extern int ___fxstat64 (int vers, int fd, struct stat64 *buf);
+
 int
-__fxstat64 (int vers, int fd, struct stat64 *buf)
+___fxstat64 (int vers, int fd, struct stat64 *buf)
 {
+  int result;
 #if __ASSUME_STAT64_SYSCALL > 0
-  return INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (buf));
+  result = INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (buf));
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+  if (!result && buf->__st_ino != (__ino_t) buf->st_ino)
+    buf->st_ino = buf->__st_ino;
+# endif
+  return result;
 #else
-  int result;
   struct kernel_stat kbuf;
 # if defined __NR_fstat64
   if (! __have_no_stat64)
@@ -58,7 +65,13 @@ __fxstat64 (int vers, int fd, struct stat64 *buf)
       result = INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (buf));
 
       if (result != -1 || errno != ENOSYS)
-	return result;
+	{
+#  if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+	  if (!result && buf->__st_ino != (__ino_t)buf->st_ino)
+	    buf->st_ino = buf->__st_ino;
+#  endif
+	  return result;
+	}
 
       __set_errno (saved_errno);
       __have_no_stat64 = 1;
@@ -71,3 +84,12 @@ __fxstat64 (int vers, int fd, struct stat64 *buf)
   return result;
 #endif
 }
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, ___fxstat64, __fxstat64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+strong_alias (___fxstat64, __old__fxstat64)
+compat_symbol (libc, __old__fxstat64, __fxstat64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/getdents.c b/sysdeps/unix/sysv/linux/getdents.c
index 0f16683eed..474bf1989b 100644
--- a/sysdeps/unix/sysv/linux/getdents.c
+++ b/sysdeps/unix/sysv/linux/getdents.c
@@ -51,9 +51,12 @@ struct kernel_dirent
     char d_name[256];
   };
 
-#ifdef GETDENTS64
-# define __getdents __getdents64
-# define dirent dirent64
+#ifndef __GETDENTS
+# define __GETDENTS __getdents
+# define DIRENT_TYPE struct dirent
+#endif
+#ifndef DIRENT_SET_DP_INO
+# define DIRENT_SET_DP_INO(dp, value) (dp)->d_ino = (value)
 #endif
 
 /* The problem here is that we cannot simply read the next NBYTES
@@ -66,22 +69,22 @@ struct kernel_dirent
    amount of data returned much more then the reduced buffer size.  */
 ssize_t
 internal_function
-__getdents (int fd, char *buf, size_t nbytes)
+__GETDENTS (int fd, char *buf, size_t nbytes)
 {
   off_t last_offset = -1;
   size_t red_nbytes;
   struct kernel_dirent *skdp, *kdp;
-  struct dirent *dp;
+  DIRENT_TYPE *dp;
   int retval;
-  const size_t size_diff = (offsetof (struct dirent, d_name)
+  const size_t size_diff = (offsetof (DIRENT_TYPE, d_name)
 			    - offsetof (struct kernel_dirent, d_name));
 
   red_nbytes = MIN (nbytes
-		    - ((nbytes / (offsetof (struct dirent, d_name) + 14))
+		    - ((nbytes / (offsetof (DIRENT_TYPE, d_name) + 14))
 		       * size_diff),
 		    nbytes - size_diff);
 
-  dp = (struct dirent *) buf;
+  dp = (DIRENT_TYPE *) buf;
   skdp = kdp = __alloca (red_nbytes);
 
   retval = INLINE_SYSCALL (getdents, 3, fd,
@@ -92,7 +95,7 @@ __getdents (int fd, char *buf, size_t nbytes)
 
   while ((char *) kdp < (char *) skdp + retval)
     {
-      const size_t alignment = __alignof__ (struct dirent);
+      const size_t alignment = __alignof__ (DIRENT_TYPE);
       /* Since kdp->d_reclen is already aligned for the kernel structure
 	 this may compute a value that is bigger than necessary.  */
       size_t new_reclen = ((kdp->d_reclen + size_diff + alignment - 1)
@@ -116,14 +119,14 @@ __getdents (int fd, char *buf, size_t nbytes)
 	}
 
       last_offset = kdp->d_off;
-      dp->d_ino = kdp->d_ino;
+      DIRENT_SET_DP_INO(dp, kdp->d_ino);
       dp->d_off = kdp->d_off;
       dp->d_reclen = new_reclen;
       dp->d_type = DT_UNKNOWN;
       memcpy (dp->d_name, kdp->d_name,
 	      kdp->d_reclen - offsetof (struct kernel_dirent, d_name));
 
-      dp = (struct dirent *) ((char *) dp + new_reclen);
+      dp = (DIRENT_TYPE *) ((char *) dp + new_reclen);
       kdp = (struct kernel_dirent *) (((char *) kdp) + kdp->d_reclen);
     }
 
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
index f50b0be615..0078ccd19f 100644
--- a/sysdeps/unix/sysv/linux/getdents64.c
+++ b/sysdeps/unix/sysv/linux/getdents64.c
@@ -1,2 +1,3 @@
-#define GETDENTS64
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
 #include <getdents.c>
diff --git a/sysdeps/unix/sysv/linux/getdirentries.c b/sysdeps/unix/sysv/linux/getdirentries.c
index cb81ad763b..b0ad4997ad 100644
--- a/sysdeps/unix/sysv/linux/getdirentries.c
+++ b/sysdeps/unix/sysv/linux/getdirentries.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -19,20 +19,21 @@
 #include <dirent.h>
 #include <unistd.h>
 
-#ifdef GETDENTS64
-# define getdirentries getdirentries64
-# define __getdents __getdents64
+#ifndef GETDIRENTRIES
+# define GETDIRENTRIES getdirentries
+# define __GETDENTS __getdents
+#else
 # define off_t off64_t
 # define __lseek __lseek64
 #endif
 
 ssize_t
-getdirentries (int fd, char *buf, size_t nbytes, off_t *basep)
+GETDIRENTRIES (int fd, char *buf, size_t nbytes, off_t *basep)
 {
   off_t base = __lseek (fd, (off_t) 0, SEEK_CUR);
   ssize_t result;
 
-  result = __getdents (fd, buf, nbytes);
+  result = __GETDENTS (fd, buf, nbytes);
 
   if (result != -1)
     *basep = base;
diff --git a/sysdeps/unix/sysv/linux/getdirentries64.c b/sysdeps/unix/sysv/linux/getdirentries64.c
index 423e361e22..e486a36a12 100644
--- a/sysdeps/unix/sysv/linux/getdirentries64.c
+++ b/sysdeps/unix/sysv/linux/getdirentries64.c
@@ -1,2 +1,3 @@
-#define GETDENTS64 1
+#define GETDIRENTRIES getdirentries64
+#define __GETDENTS __getdents64
 #include "getdirentries.c"
diff --git a/sysdeps/unix/sysv/linux/i386/Versions b/sysdeps/unix/sysv/linux/i386/Versions
index 8dc447ed81..58c7b3d9b1 100644
--- a/sysdeps/unix/sysv/linux/i386/Versions
+++ b/sysdeps/unix/sysv/linux/i386/Versions
@@ -13,7 +13,24 @@ libc {
     __modify_ldt; modify_ldt;
   }
   GLIBC_2.2 {
+    # functions used in other libraries
+    __xstat64; __fxstat64; __lxstat64;
+
+    # a*
+    alphasort64;
+
+    # g*
+    getdirentries64;
     # New rlimit interface
     getrlimit; setrlimit; getrlimit64;
+
+    # r*
+    readdir64; readdir64_r;
+
+    # s*
+    scandir64;
+
+    # v*
+    versionsort64;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/i386/alphasort64.c b/sysdeps/unix/sysv/linux/i386/alphasort64.c
new file mode 100644
index 0000000000..3f8d89c76b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/alphasort64.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1992, 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <dirent.h>
+#include <string.h>
+
+int
+__alphasort64 (const void *a, const void *b)
+{
+  return strcoll ((*(const struct dirent64 **) a)->d_name,
+		  (*(const struct dirent64 **) b)->d_name);
+}
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __alphasort64, alphasort64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+int
+__old_alphasort64 (const void *a, const void *b);
+
+int
+__old_alphasort64 (const void *a, const void *b)
+{
+  return strcoll ((*(const struct __old_dirent64 **) a)->d_name,
+                    (*(const struct __old_dirent64 **) b)->d_name);
+}
+
+compat_symbol (libc, __old_alphasort64, alphasort64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/getdents64.c b/sysdeps/unix/sysv/linux/i386/getdents64.c
new file mode 100644
index 0000000000..dac046fa0c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/getdents64.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/sysv/linux/getdents.c>
+
+#include <shlib-compat.h>
+
+#undef __READDIR
+#undef __GETDENTS
+#undef DIRENT_TYPE
+
+versioned_symbol (libc, __getdents64, getdents64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define __GETDENTS __old_getdents64
+#define DIRENT_TYPE struct __old_dirent64
+#define kernel_dirent old_kernel_dirent
+
+#include <sysdeps/unix/sysv/linux/getdents.c>
+
+compat_symbol (libc, __old_getdents64, getdents64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/olddirent.h b/sysdeps/unix/sysv/linux/i386/olddirent.h
new file mode 100644
index 0000000000..bcce37bfa5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/olddirent.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef __OLD_DIRENT_H
+#define __OLD_DIRENT_H 1
+
+#include <dirent.h>
+
+struct __old_dirent64
+  {
+    __ino_t d_ino;
+    __off64_t d_off;
+    unsigned short int d_reclen;
+    unsigned char d_type;
+    char d_name[256];		/* We must not include limits.h! */
+  };
+
+/* Now define the internal interfaces.  */
+extern struct __old_dirent64 *__old_readdir64 (DIR *__dirp);
+extern int __old_readdir64_r (DIR *__dirp, struct __old_dirent64 *__entry,
+                          struct __old_dirent64 **__result);
+extern __ssize_t __old_getdents64 (int __fd, char *__buf, size_t __nbytes)
+	internal_function;
+int __old_scandir64 (__const char * __dir,
+		     struct __old_dirent64 *** __namelist,
+		     int (*__selector) (__const struct __old_dirent64 *),
+		     int (*__cmp) (__const void *, __const void *));
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64.c b/sysdeps/unix/sysv/linux/i386/readdir64.c
new file mode 100644
index 0000000000..669ef9dbf7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/readdir64.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#define __READDIR __readdir64
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/readdir.c>
+
+#include <shlib-compat.h>
+
+#undef __READDIR
+#undef __GETDENTS
+#undef DIRENT_TYPE
+
+versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define __READDIR __old_readdir64
+#define __GETDENTS __old_getdents64
+#define DIRENT_TYPE struct __old_dirent64
+
+#include <sysdeps/unix/readdir.c>
+
+compat_symbol (libc, __old_readdir64, readdir64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
new file mode 100644
index 0000000000..96e975d114
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#define __READDIR_R __readdir64_r
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
+
+#include <sysdeps/unix/readdir_r.c>
+
+#undef __READDIR_R
+#undef __GETDENTS
+#undef DIRENT_TYPE
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define __READDIR_R __old_readdir64_r
+#define __GETDENTS __old_getdents64
+#define DIRENT_TYPE struct __old_dirent64
+
+#include <sysdeps/unix/readdir_r.c>
+
+compat_symbol (libc, __old_readdir64_r, readdir64_r, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/scandir64.c b/sysdeps/unix/sysv/linux/i386/scandir64.c
new file mode 100644
index 0000000000..95e5c73670
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/scandir64.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <dirent.h>
+
+#define SCANDIR __scandir64
+#define READDIR __readdir64
+#define DIRENT_TYPE struct dirent64
+
+#include <dirent/scandir.c>
+
+#undef SCANDIR
+#undef READDIR
+#undef DIRENT_TYPE
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __scandir64, scandir64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+#define SCANDIR __old_scandir64
+#define READDIR __old_readdir64
+#define DIRENT_TYPE struct __old_dirent64
+
+#include <dirent/scandir.c>
+
+compat_symbol (libc, __old_scandir64, scandir64, GLIBC_2_1);
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/versionsort64.c b/sysdeps/unix/sysv/linux/i386/versionsort64.c
new file mode 100644
index 0000000000..fbaaea2e1e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/versionsort64.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1992, 1997, 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <dirent.h>
+#include <string.h>
+
+int
+__versionsort64 (const void *a, const void *b)
+{
+  return __strverscmp ((*(const struct dirent64 **) a)->d_name,
+		       (*(const struct dirent64 **) b)->d_name);
+}
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __versionsort64, versionsort64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+
+#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+
+int
+__old_versionsort64 (const void *a, const void *b);
+
+int
+__old_versionsort64 (const void *a, const void *b)
+{
+  return __strverscmp ((*(const struct __old_dirent64 **) a)->d_name,
+		       (*(const struct __old_dirent64 **) b)->d_name);
+}
+                      
+compat_symbol (libc, __old_versionsort64, versionsort64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/ia64/getdents.c b/sysdeps/unix/sysv/linux/ia64/getdents.c
new file mode 100644
index 0000000000..491fa9dfb2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/getdents.c
@@ -0,0 +1,4 @@
+#define __getdents64 __no___getdents64_decl
+#include <sysdeps/unix/sysv/linux/getdents.c>
+#undef __getdents64
+weak_alias(__getdents, __getdents64);
diff --git a/sysdeps/unix/sysv/linux/ia64/getdents64.c b/sysdeps/unix/sysv/linux/ia64/getdents64.c
new file mode 100644
index 0000000000..0df2c8f4c6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/getdents64.c
@@ -0,0 +1 @@
+/* getdents64 is in getdents.c */
diff --git a/sysdeps/unix/sysv/linux/ia64/readdir.c b/sysdeps/unix/sysv/linux/ia64/readdir.c
index 300ebb2629..e64b2f8bdd 100644
--- a/sysdeps/unix/sysv/linux/ia64/readdir.c
+++ b/sysdeps/unix/sysv/linux/ia64/readdir.c
@@ -1,7 +1 @@
-#define readdir64 __no_readdir64_decl
-#define __readdir64 __no___readdir64_decl
-#include <sysdeps/unix/readdir.c>
-#undef __readdir64
-strong_alias (__readdir, __readdir64)
-#undef readdir64
-weak_alias (__readdir, readdir64)
+#include <sysdeps/unix/sysv/linux/alpha/readdir.c>
diff --git a/sysdeps/unix/sysv/linux/ia64/readdir_r.c b/sysdeps/unix/sysv/linux/ia64/readdir_r.c
index adb92db6af..fc5818fa19 100644
--- a/sysdeps/unix/sysv/linux/ia64/readdir_r.c
+++ b/sysdeps/unix/sysv/linux/ia64/readdir_r.c
@@ -1,4 +1 @@
-#define readdir64_r __no_readdir64_r_decl
-#include <sysdeps/unix/readdir_r.c>
-#undef readdir64_r
-weak_alias (__readdir_r, readdir64_r)
+#include <sysdeps/unix/sysv/linux/alpha/readdir_r.c>
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index babeab56a4..8790057e48 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -122,3 +122,10 @@
 #if __LINUX_KERNEL_VERSION >= 131939
 # define __ASSUME_LDT_WORKS		1
 #endif
+
+/* The changed st_ino field appeared in 2.4.0-test6.  But we cannot
+   distinguish this version from other 2.4.0 releases.  Therefore play
+   save and assume it available for 2.4.1 and up.  */
+#if __LINUX_KERNEL_VERSION >= 132097
+# define __ASSUME_ST_INO_64_BIT		1
+#endif
diff --git a/sysdeps/unix/sysv/linux/kernel_stat.h b/sysdeps/unix/sysv/linux/kernel_stat.h
index bd7ddcc9bc..7f4f91f43e 100644
--- a/sysdeps/unix/sysv/linux/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/kernel_stat.h
@@ -29,3 +29,17 @@ struct kernel_stat
     unsigned long int __unused5;
 #define _HAVE___UNUSED5
   };
+
+#define _HAVE_STAT___UNUSED1
+#define _HAVE_STAT___UNUSED2
+#define _HAVE_STAT___UNUSED3
+#define _HAVE_STAT___UNUSED4
+#define _HAVE_STAT___UNUSED5
+#define _HAVE_STAT___PAD1
+#define _HAVE_STAT___PAD2
+#define _HAVE_STAT64___UNUSED1
+#define _HAVE_STAT64___UNUSED2
+#define _HAVE_STAT64___UNUSED3
+#define _HAVE_STAT64___PAD1
+#define _HAVE_STAT64___PAD2
+#define _HAVE_STAT64___ST_INO
diff --git a/sysdeps/unix/sysv/linux/lxstat64.c b/sysdeps/unix/sysv/linux/lxstat64.c
index 44097653c7..1192940d48 100644
--- a/sysdeps/unix/sysv/linux/lxstat64.c
+++ b/sysdeps/unix/sysv/linux/lxstat64.c
@@ -32,10 +32,12 @@
 # include <xstatconv.c>
 #endif
 
-extern int __syscall_lstat (const char *__unbounded, struct kernel_stat *__unbounded);
+extern int __syscall_lstat (const char *__unbounded,
+			    struct kernel_stat *__unbounded);
 
 #ifdef __NR_lstat64
-extern int __syscall_lstat64 (const char *__unbounded, struct stat64 *__unbounded);
+extern int __syscall_lstat64 (const char *__unbounded,
+			      struct stat64 *__unbounded);
 # if  __ASSUME_STAT64_SYSCALL == 0
 /* The variable is shared between all wrappers around *stat64 calls.  */
 extern int __have_no_stat64;
@@ -43,14 +45,21 @@ extern int __have_no_stat64;
 #endif
 
 /* Get information about the file NAME in BUF.  */
+extern int ___lxstat64 (int vers, const char *name, struct stat64 *buf);
+
 int
-__lxstat64 (int vers, const char *name, struct stat64 *buf)
+___lxstat64 (int vers, const char *name, struct stat64 *buf)
 {
+  int result;
 #ifdef __ASSUME_STAT64_SYSCALL
-  return INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+  result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+  if (!result && buf->__st_ino != (__ino_t)buf->st_ino)
+    buf->st_ino = buf->__st_ino;
+# endif
+  return result;
 #else
   struct kernel_stat kbuf;
-  int result;
 # ifdef __NR_lstat64
   if (! __have_no_stat64)
     {
@@ -58,7 +67,13 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
       result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), CHECK_1 (buf));
 
       if (result != -1 || errno != ENOSYS)
-	return result;
+	{
+#  if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+	  if (!result && buf->__st_ino != (__ino_t)buf->st_ino)
+	    buf->st_ino = buf->__st_ino;
+#  endif
+	  return result;
+	}
 
       __set_errno (saved_errno);
       __have_no_stat64 = 1;
@@ -71,3 +86,12 @@ __lxstat64 (int vers, const char *name, struct stat64 *buf)
   return result;
 #endif
 }
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, ___lxstat64, __lxstat64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+strong_alias (___lxstat64, __old__lxstat64)
+compat_symbol (libc, __old__lxstat64, __lxstat64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types.h b/sysdeps/unix/sysv/linux/mips/bits/types.h
index 6bb07e7b13..379f2bcd32 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/types.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/types.h
@@ -137,7 +137,7 @@ typedef __u_long __fsfilcnt_t;
 typedef __u_quad_t __fsfilcnt64_t;
 
 /* Type of file serial numbers.  */
-typedef __u_long __ino64_t;
+typedef __u_quad_t __ino64_t;
 
 /* Type of file sizes and offsets.  */
 typedef __loff_t __off64_t;
diff --git a/sysdeps/unix/sysv/linux/powerpc/Versions b/sysdeps/unix/sysv/linux/powerpc/Versions
index 0f2b4c77eb..6466be2cc5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Versions
+++ b/sysdeps/unix/sysv/linux/powerpc/Versions
@@ -6,7 +6,24 @@ libc {
     __register_frame_info_table;
   }
   GLIBC_2.2 {
+    # functions used in other libraries
+    __xstat64; __fxstat64; __lxstat64;
+
+    # a*
+    alphasort64;
+
+    # g*
+    getdirentries64;
     # New rlimit interface
     getrlimit; setrlimit; getrlimit64; setrlimit64;
+
+    # r*
+    readdir64; readdir64_r;
+
+    # s*
+    scandir64;
+
+    # v*
+    versionsort64;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/stat.h b/sysdeps/unix/sysv/linux/powerpc/bits/stat.h
new file mode 100644
index 0000000000..8f1dffacab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/stat.h
@@ -0,0 +1,128 @@
+/* Copyright (C) 1992, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure.  */
+#define _STAT_VER_LINUX_OLD	1
+#define _STAT_VER_KERNEL	1
+#define _STAT_VER_SVR4		2
+#define _STAT_VER_LINUX		3
+#define _STAT_VER		_STAT_VER_LINUX	/* The one defined below.  */
+
+/* Versions of the `xmknod' interface.  */
+#define _MKNOD_VER_LINUX	1
+#define _MKNOD_VER_SVR4		2
+#define _MKNOD_VER		_MKNOD_VER_LINUX /* The bits defined below.  */
+
+
+struct stat
+  {
+    __dev_t st_dev;			/* Device.  */
+#ifndef __USE_FILE_OFFSET64
+    unsigned short int __pad1;
+    __ino_t st_ino;			/* File serial number.	*/
+#else
+    __ino64_t st_ino;			/* File serial number.	*/
+#endif
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    unsigned short int __pad2;
+#ifndef __USE_FILE_OFFSET64
+    __off_t st_size;			/* Size of file, in bytes.  */
+#else
+    __off64_t st_size;			/* Size of file, in bytes.  */
+#endif
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+#ifndef __USE_FILE_OFFSET64
+    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+#else
+    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+#endif
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int __unused1;
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int __unused2;
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int __unused3;
+    unsigned long int __unused4;
+    unsigned long int __unused5;
+  };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+  {
+    __dev_t st_dev;			/* Device.  */
+    __ino64_t st_ino;			/* File serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    unsigned short int __pad2;
+    __off64_t st_size;			/* Size of file, in bytes.  */
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int __unused1;
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int __unused2;
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int __unused3;
+    unsigned long int __unused4;
+    unsigned long int __unused5;
+  };
+#endif
+
+/* Tell code we have these members.  */
+#define	_STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+
+/* Encoding of the file mode.  */
+
+#define	__S_IFMT	0170000	/* These bits determine file type.  */
+
+/* File types.  */
+#define	__S_IFDIR	0040000	/* Directory.  */
+#define	__S_IFCHR	0020000	/* Character device.  */
+#define	__S_IFBLK	0060000	/* Block device.  */
+#define	__S_IFREG	0100000	/* Regular file.  */
+#define	__S_IFIFO	0010000	/* FIFO.  */
+#define	__S_IFLNK	0120000	/* Symbolic link.  */
+#define	__S_IFSOCK	0140000	/* Socket.  */
+
+/* POSIX.1b objects.  */
+#define __S_TYPEISMQ(buf) (0)
+#define __S_TYPEISSEM(buf) (0)
+#define __S_TYPEISSHM(buf) (0)
+
+/* Protection bits.  */
+
+#define	__S_ISUID	04000	/* Set user ID on execution.  */
+#define	__S_ISGID	02000	/* Set group ID on execution.  */
+#define	__S_ISVTX	01000	/* Save swapped text after use (sticky).  */
+#define	__S_IREAD	0400	/* Read by owner.  */
+#define	__S_IWRITE	0200	/* Write by owner.  */
+#define	__S_IEXEC	0100	/* Execute by owner.  */
diff --git a/sysdeps/unix/sysv/linux/powerpc/getdents64.c b/sysdeps/unix/sysv/linux/powerpc/getdents64.c
new file mode 100644
index 0000000000..0c75fb5a06
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/getdents64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getdents64.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_stat.h b/sysdeps/unix/sysv/linux/powerpc/kernel_stat.h
index c07e182748..d51170e820 100644
--- a/sysdeps/unix/sysv/linux/powerpc/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/powerpc/kernel_stat.h
@@ -1,5 +1,5 @@
 /* Definition of `struct stat' used in the kernel.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -43,3 +43,17 @@ struct kernel_stat
     unsigned long int __unused5;
 #define _HAVE___UNUSED5
   };
+
+#define _HAVE_STAT___UNUSED1
+#define _HAVE_STAT___UNUSED2
+#define _HAVE_STAT___UNUSED3
+#define _HAVE_STAT___UNUSED4
+#define _HAVE_STAT___UNUSED5
+#define _HAVE_STAT___PAD1
+#define _HAVE_STAT___PAD2
+#define _HAVE_STAT64___UNUSED1
+#define _HAVE_STAT64___UNUSED2
+#define _HAVE_STAT64___UNUSED3
+#define _HAVE_STAT64___UNUSED4
+#define _HAVE_STAT64___UNUSED5
+#define _HAVE_STAT64___PAD2
diff --git a/sysdeps/unix/sysv/linux/powerpc/readdir64.c b/sysdeps/unix/sysv/linux/powerpc/readdir64.c
new file mode 100644
index 0000000000..2ea26dd409
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/readdir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/readdir64_r.c b/sysdeps/unix/sysv/linux/powerpc/readdir64_r.c
new file mode 100644
index 0000000000..9f54f897e3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/readdir64_r.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64_r.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/scandir64.c b/sysdeps/unix/sysv/linux/powerpc/scandir64.c
new file mode 100644
index 0000000000..506fd8877c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/scandir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/scandir64.c>
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
index 5a19e220aa..9341e3bd13 100644
--- a/sysdeps/unix/sysv/linux/readdir64.c
+++ b/sysdeps/unix/sysv/linux/readdir64.c
@@ -1,99 +1,14 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
+#define __READDIR __readdir64
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
 
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+#include <sysdeps/unix/readdir.c>
 
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
+#include <shlib-compat.h>
 
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
 
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <string.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <assert.h>
-
-#include <dirstream.h>
-
-/* Read a directory entry from DIRP.  */
-struct dirent64 *
-__readdir64 (DIR *dirp)
-{
-  struct dirent64 *dp;
-
-  __libc_lock_lock (dirp->lock);
-
-  do
-    {
-      size_t reclen;
-
-      if (dirp->offset >= dirp->size)
-	{
-	  /* We've emptied out our buffer.  Refill it.  */
-
-	  size_t maxread;
-	  ssize_t bytes;
-
-#ifndef _DIRENT_HAVE_D_RECLEN
-	  /* Fixed-size struct; must read one at a time (see below).  */
-	  maxread = sizeof *dp;
-#else
-	  maxread = dirp->allocation;
-#endif
-
-	  bytes = __getdents64 (dirp->fd, dirp->data, maxread);
-	  if (bytes <= 0)
-	    {
-	      dp = NULL;
-	      break;
-	    }
-	  dirp->size = (size_t) bytes;
-
-	  /* Reset the offset into the buffer.  */
-	  dirp->offset = 0;
-	}
-
-      dp = (struct dirent64 *) &dirp->data[dirp->offset];
-
-#ifdef _DIRENT_HAVE_D_RECLEN
-      reclen = dp->d_reclen;
-#else
-      /* The only version of `struct dirent64' that lacks `d_reclen'
-	 is fixed-size.  */
-      assert (sizeof dp->d_name > 1);
-      reclen = sizeof *dp;
-      /* The name is not terminated if it is the largest possible size.
-	 Clobber the following byte to ensure proper null termination.  We
-	 read jst one entry at a time above so we know that byte will not
-	 be used later.  */
-      dp->d_name[sizeof dp->d_name] = '\0';
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__readdir64, __old_readdir64)
+compat_symbol (libc, __old_readdir64, readdir64, GLIBC_2_1);
 #endif
-
-      dirp->offset += reclen;
-
-#ifdef _DIRENT_HAVE_D_OFF
-      dirp->filepos = dp->d_off;
-#else
-      dirp->filepos += reclen;
-#endif
-
-      /* Skip deleted files.  */
-    } while (dp->d_ino == 0);
-
-  __libc_lock_unlock (dirp->lock);
-
-  return dp;
-}
-weak_alias (__readdir64, readdir64)
diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c
index a86ef7b8d2..63a6b80f95 100644
--- a/sysdeps/unix/sysv/linux/readdir64_r.c
+++ b/sysdeps/unix/sysv/linux/readdir64_r.c
@@ -1,106 +1,14 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
+#define __READDIR_R __readdir64_r
+#define __GETDENTS __getdents64
+#define DIRENT_TYPE struct dirent64
 
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+#include <sysdeps/unix/readdir_r.c>
 
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
+#include <shlib-compat.h>
 
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
 
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <string.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <assert.h>
-
-#include <dirstream.h>
-
-/* Read a directory entry from DIRP, store result in ENTRY and return
-   pointer to result in *RESULT.  */
-int
-readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
-{
-  struct dirent64 *dp;
-  size_t reclen;
-
-  __libc_lock_lock (dirp->lock);
-
-  do
-    {
-      if (dirp->offset >= dirp->size)
-	{
-	  /* We've emptied out our buffer.  Refill it.  */
-
-	  size_t maxread;
-	  ssize_t bytes;
-
-#ifndef _DIRENT_HAVE_D_RECLEN
-	  /* Fixed-size struct; must read one at a time (see below).  */
-	  maxread = sizeof *dp;
-#else
-	  maxread = dirp->allocation;
-#endif
-
-	  bytes = __getdents64 (dirp->fd, dirp->data, maxread);
-	  if (bytes <= 0)
-	    {
-	      dp = NULL;
-	      /* Reclen != 0 signals that an error occurred.  */
-	      reclen = bytes != 0;
-	      break;
-	    }
-	  dirp->size = (size_t) bytes;
-
-	  /* Reset the offset into the buffer.  */
-	  dirp->offset = 0;
-	}
-
-      dp = (struct dirent64 *) &dirp->data[dirp->offset];
-
-#ifdef _DIRENT_HAVE_D_RECLEN
-      reclen = dp->d_reclen;
-#else
-      /* The only version of `struct dirent64' that lacks `d_reclen'
-	 is fixed-size.  */
-      assert (sizeof dp->d_name > 1);
-      reclen = sizeof *dp;
-      /* The name is not terminated if it is the largest possible size.
-	 Clobber the following byte to ensure proper null termination.  We
-	 read just one entry at a time above so we know that byte will not
-	 be used later.  */
-      dp->d_name[sizeof dp->d_name] = '\0';
-#endif
-
-      dirp->offset += reclen;
-
-#ifdef _DIRENT_HAVE_D_OFF
-      dirp->filepos = dp->d_off;
-#else
-      dirp->filepos += reclen;
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__readdir64_r, __old_readdir64_r)
+compat_symbol (libc, __old_readdir64_r, readdir64_r, GLIBC_2_1);
 #endif
-
-      /* Skip deleted files.  */
-    }
-  while (dp->d_ino == 0);
-
-  if (dp != NULL)
-    *result = memcpy (entry, dp, reclen);
-  else
-    *result = NULL;
-
-  __libc_lock_unlock (dirp->lock);
-
-  return dp != NULL ? 0 : reclen ? errno : 0;
-}
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/stat.h b/sysdeps/unix/sysv/linux/sparc/bits/stat.h
new file mode 100644
index 0000000000..7fe9d4038e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/bits/stat.h
@@ -0,0 +1,131 @@
+/* Copyright (C) 1992, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _SYS_STAT_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+/* Versions of the `struct stat' data structure.  */
+#define _STAT_VER_LINUX_OLD	1
+#define _STAT_VER_KERNEL	1
+#define _STAT_VER_SVR4		2
+#define _STAT_VER_LINUX		3
+#define _STAT_VER		_STAT_VER_LINUX	/* The one defined below.  */
+
+/* Versions of the `xmknod' interface.  */
+#define _MKNOD_VER_LINUX	1
+#define _MKNOD_VER_SVR4		2
+#define _MKNOD_VER		_MKNOD_VER_LINUX /* The bits defined below.  */
+
+
+struct stat
+  {
+    __dev_t st_dev;			/* Device.  */
+#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
+    unsigned short int __pad1;
+    __ino_t st_ino;			/* File serial number.	*/
+#else
+    __ino64_t st_ino;			/* File serial number.	*/
+#endif
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    unsigned short int __pad2;
+#ifndef __USE_FILE_OFFSET64
+    __off_t st_size;			/* Size of file, in bytes.  */
+#else
+    __off64_t st_size;			/* Size of file, in bytes.  */
+#endif
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+#ifndef __USE_FILE_OFFSET64
+    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+#else
+    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+#endif
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int __unused1;
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int __unused2;
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int __unused3;
+    unsigned long int __unused4;
+    unsigned long int __unused5;
+  };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+  {
+    __dev_t st_dev;			/* Device.  */
+#if __WORDSIZE == 64
+    unsigned short int __pad1;
+#endif    
+    __ino64_t st_ino;			/* File serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    unsigned short int __pad2;
+    __off64_t st_size;			/* Size of file, in bytes.  */
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int __unused1;
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int __unused2;
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int __unused3;
+    unsigned long int __unused4;
+    unsigned long int __unused5;
+  };
+#endif
+
+/* Tell code we have these members.  */
+#define	_STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+
+/* Encoding of the file mode.  */
+
+#define	__S_IFMT	0170000	/* These bits determine file type.  */
+
+/* File types.  */
+#define	__S_IFDIR	0040000	/* Directory.  */
+#define	__S_IFCHR	0020000	/* Character device.  */
+#define	__S_IFBLK	0060000	/* Block device.  */
+#define	__S_IFREG	0100000	/* Regular file.  */
+#define	__S_IFIFO	0010000	/* FIFO.  */
+#define	__S_IFLNK	0120000	/* Symbolic link.  */
+#define	__S_IFSOCK	0140000	/* Socket.  */
+
+/* POSIX.1b objects.  */
+#define __S_TYPEISMQ(buf) (0)
+#define __S_TYPEISSEM(buf) (0)
+#define __S_TYPEISSHM(buf) (0)
+
+/* Protection bits.  */
+
+#define	__S_ISUID	04000	/* Set user ID on execution.  */
+#define	__S_ISGID	02000	/* Set group ID on execution.  */
+#define	__S_ISVTX	01000	/* Save swapped text after use (sticky).  */
+#define	__S_IREAD	0400	/* Read by owner.  */
+#define	__S_IWRITE	0200	/* Write by owner.  */
+#define	__S_IEXEC	0100	/* Execute by owner.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types.h b/sysdeps/unix/sysv/linux/sparc/bits/types.h
index 8d76cd7e83..191315ff0b 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/types.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/types.h
@@ -73,7 +73,7 @@ typedef __u_quad_t __dev_t;		/* Type of device numbers.  */
 typedef __u_int __uid_t;		/* Type of user identifications.  */
 typedef __u_int __gid_t;		/* Type of group identifications.  */
 typedef __u_long __ino_t;		/* Type of file serial numbers.  */
-typedef __u_long __ino64_t;		/* Type of file serial numbers.  */
+typedef __u_quad_t __ino64_t;		/* Type of file serial numbers.  */
 typedef __u_int __mode_t;		/* Type of file attribute bitmasks.  */
 typedef __u_int __nlink_t; 		/* Type of file link counts.  */
 typedef long int __off_t;		/* Type of file sizes and offsets.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Versions b/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
index 2d3061bad5..fcb9df31ec 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Versions
@@ -5,4 +5,23 @@ libc {
     __register_frame_info; __deregister_frame_info; __frame_state_for;
     __register_frame_info_table;
   }
+  GLIBC_2.2 {
+    # functions used in other libraries
+    __xstat64; __fxstat64; __lxstat64;
+
+    # a*
+    alphasort64;
+
+    # g*
+    getdirentries64;
+
+    # r*
+    readdir64; readdir64_r;
+
+    # s*
+    scandir64;
+
+    # v*
+    versionsort64;
+  }
 }
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c b/sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c
new file mode 100644
index 0000000000..0c75fb5a06
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getdents64.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
index 91f02f4e20..ec2804687d 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h
@@ -26,3 +26,17 @@ struct kernel_stat
 #define _HAVE___UNUSED3
 #define _HAVE___UNUSED4
 #define _HAVE___UNUSED5
+
+#define _HAVE_STAT___UNUSED1
+#define _HAVE_STAT___UNUSED2
+#define _HAVE_STAT___UNUSED3
+#define _HAVE_STAT___UNUSED4
+#define _HAVE_STAT___UNUSED5
+#define _HAVE_STAT___PAD1
+#define _HAVE_STAT___PAD2
+#define _HAVE_STAT64___UNUSED1
+#define _HAVE_STAT64___UNUSED2
+#define _HAVE_STAT64___UNUSED3
+#define _HAVE_STAT64___UNUSED4
+#define _HAVE_STAT64___UNUSED5
+#define _HAVE_STAT64___PAD2
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c b/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c
new file mode 100644
index 0000000000..2ea26dd409
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c b/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c
new file mode 100644
index 0000000000..9f54f897e3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/readdir64_r.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c b/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c
new file mode 100644
index 0000000000..506fd8877c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/scandir64.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/getdents.c b/sysdeps/unix/sysv/linux/sparc/sparc64/getdents.c
new file mode 100644
index 0000000000..491fa9dfb2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/getdents.c
@@ -0,0 +1,4 @@
+#define __getdents64 __no___getdents64_decl
+#include <sysdeps/unix/sysv/linux/getdents.c>
+#undef __getdents64
+weak_alias(__getdents, __getdents64);
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/getdents64.c b/sysdeps/unix/sysv/linux/sparc/sparc64/getdents64.c
new file mode 100644
index 0000000000..0df2c8f4c6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/getdents64.c
@@ -0,0 +1 @@
+/* getdents64 is in getdents.c */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
index 05457fc78e..700dd127d0 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h
@@ -21,4 +21,19 @@ struct kernel_stat
 #define _HAVE___UNUSED1
 #define _HAVE___UNUSED2
 
+#define _HAVE_STAT___UNUSED1
+#define _HAVE_STAT___UNUSED2
+#define _HAVE_STAT___UNUSED3
+#define _HAVE_STAT___UNUSED4
+#define _HAVE_STAT___UNUSED5
+#define _HAVE_STAT___PAD1
+#define _HAVE_STAT___PAD2
+#define _HAVE_STAT64___UNUSED1
+#define _HAVE_STAT64___UNUSED2
+#define _HAVE_STAT64___UNUSED3
+#define _HAVE_STAT64___UNUSED4
+#define _HAVE_STAT64___UNUSED5
+#define _HAVE_STAT64___PAD1
+#define _HAVE_STAT64___PAD2
+
 #define XSTAT_IS_XSTAT64 1
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c b/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c
index 300ebb2629..e64b2f8bdd 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c
@@ -1,7 +1 @@
-#define readdir64 __no_readdir64_decl
-#define __readdir64 __no___readdir64_decl
-#include <sysdeps/unix/readdir.c>
-#undef __readdir64
-strong_alias (__readdir, __readdir64)
-#undef readdir64
-weak_alias (__readdir, readdir64)
+#include <sysdeps/unix/sysv/linux/alpha/readdir.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/readdir_r.c b/sysdeps/unix/sysv/linux/sparc/sparc64/readdir_r.c
index adb92db6af..fc5818fa19 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/readdir_r.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/readdir_r.c
@@ -1,4 +1 @@
-#define readdir64_r __no_readdir64_r_decl
-#include <sysdeps/unix/readdir_r.c>
-#undef readdir64_r
-weak_alias (__readdir_r, readdir64_r)
+#include <sysdeps/unix/sysv/linux/alpha/readdir_r.c>
diff --git a/sysdeps/unix/sysv/linux/xstat64.c b/sysdeps/unix/sysv/linux/xstat64.c
index 55d4bea57a..f52cb7a42c 100644
--- a/sysdeps/unix/sysv/linux/xstat64.c
+++ b/sysdeps/unix/sysv/linux/xstat64.c
@@ -1,5 +1,5 @@
 /* xstat64 using old-style Unix stat system call.
-   Copyright (C) 1991, 95, 96, 97, 98, 99, 00 Free Software Foundation, Inc.
+   Copyright (C) 1991, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -32,10 +32,12 @@
 # include <xstatconv.c>
 #endif
 
-extern int __syscall_stat (const char *__unbounded, struct kernel_stat *__unbounded);
+extern int __syscall_stat (const char *__unbounded,
+			   struct kernel_stat *__unbounded);
 
 #ifdef __NR_stat64
-extern int __syscall_stat64 (const char *__unbounded, struct stat64 *__unbounded);
+extern int __syscall_stat64 (const char *__unbounded,
+			     struct stat64 *__unbounded);
 # if  __ASSUME_STAT64_SYSCALL == 0
 /* The variable is shared between all wrappers around *stat64 calls.
    This is the definition.  */
@@ -46,13 +48,21 @@ int __have_no_stat64;
 /* Get information about the file NAME in BUF.  */
 
 int
-__xstat64 (int vers, const char *name, struct stat64 *buf)
+___xstat64 (int vers, const char *name, struct stat64 *buf);
+
+int
+___xstat64 (int vers, const char *name, struct stat64 *buf)
 {
+  int result;
 #if __ASSUME_STAT64_SYSCALL > 0
-  return INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+  result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (buf));
+# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+  if (!result && buf->__st_ino != (__ino_t) buf->st_ino)
+    buf->st_ino = buf->__st_ino;
+# endif
+  return result;
 #else
   struct kernel_stat kbuf;
-  int result;
 # if defined __NR_stat64
   if (! __have_no_stat64)
     {
@@ -60,7 +70,13 @@ __xstat64 (int vers, const char *name, struct stat64 *buf)
       result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (buf));
 
       if (result != -1 || errno != ENOSYS)
-	return result;
+	{
+#  if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
+	  if (!result && buf->__st_ino != (__ino_t) buf->st_ino)
+	    buf->st_ino = buf->__st_ino;
+#  endif
+	  return result;
+	}
 
       __set_errno (saved_errno);
       __have_no_stat64 = 1;
@@ -74,3 +90,12 @@ __xstat64 (int vers, const char *name, struct stat64 *buf)
   return result;
 #endif
 }
+
+#include <shlib-compat.h>
+
+versioned_symbol (libc, ___xstat64, __xstat64, GLIBC_2_2);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+strong_alias (___xstat64, __old__xstat64)
+compat_symbol (libc, __old__xstat64, __xstat64, GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/xstatconv.c b/sysdeps/unix/sysv/linux/xstatconv.c
index d9b48d13ea..21620a2e00 100644
--- a/sysdeps/unix/sysv/linux/xstatconv.c
+++ b/sysdeps/unix/sysv/linux/xstatconv.c
@@ -38,7 +38,7 @@ xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
 
 	/* Convert to current kernel version of `struct stat'.  */
 	buf->st_dev = kbuf->st_dev;
-#ifdef _HAVE___PAD1
+#ifdef _HAVE_STAT___PAD1
 	buf->__pad1 = 0;
 #endif
 	buf->st_ino = kbuf->st_ino;
@@ -47,28 +47,28 @@ xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
 	buf->st_uid = kbuf->st_uid;
 	buf->st_gid = kbuf->st_gid;
 	buf->st_rdev = kbuf->st_rdev;
-#ifdef _HAVE___PAD2
+#ifdef _HAVE_STAT___PAD2
 	buf->__pad2 = 0;
 #endif
 	buf->st_size = kbuf->st_size;
 	buf->st_blksize = kbuf->st_blksize;
 	buf->st_blocks = kbuf->st_blocks;
 	buf->st_atime = kbuf->st_atime;
-#ifdef _HAVE___UNUSED1
+#ifdef _HAVE_STAT___UNUSED1
 	buf->__unused1 = 0;
 #endif
 	buf->st_mtime = kbuf->st_mtime;
-#ifdef _HAVE___UNUSED2
+#ifdef _HAVE_STAT___UNUSED2
 	buf->__unused2 = 0;
 #endif
 	buf->st_ctime = kbuf->st_ctime;
-#ifdef _HAVE___UNUSED3
+#ifdef _HAVE_STAT___UNUSED3
 	buf->__unused3 = 0;
 #endif
-#ifdef _HAVE___UNUSED4
+#ifdef _HAVE_STAT___UNUSED4
 	buf->__unused4 = 0;
 #endif
-#ifdef _HAVE___UNUSED5
+#ifdef _HAVE_STAT___UNUSED5
 	buf->__unused5 = 0;
 #endif
       }
@@ -96,37 +96,40 @@ xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
 
 	/* Convert to current kernel version of `struct stat64'.  */
 	buf->st_dev = kbuf->st_dev;
-#ifdef _HAVE___PAD1
+#ifdef _HAVE_STAT64___PAD1
 	buf->__pad1 = 0;
 #endif
 	buf->st_ino = kbuf->st_ino;
+#ifdef _HAVE_STAT64___ST_INO
+	buf->__st_ino = kbuf->st_ino;
+#endif
 	buf->st_mode = kbuf->st_mode;
 	buf->st_nlink = kbuf->st_nlink;
 	buf->st_uid = kbuf->st_uid;
 	buf->st_gid = kbuf->st_gid;
 	buf->st_rdev = kbuf->st_rdev;
-#ifdef _HAVE___PAD2
+#ifdef _HAVE_STAT64___PAD2
 	buf->__pad2 = 0;
 #endif
 	buf->st_size = kbuf->st_size;
 	buf->st_blksize = kbuf->st_blksize;
 	buf->st_blocks = kbuf->st_blocks;
 	buf->st_atime = kbuf->st_atime;
-#ifdef _HAVE___UNUSED1
+#ifdef _HAVE_STAT64___UNUSED1
 	buf->__unused1 = 0;
 #endif
 	buf->st_mtime = kbuf->st_mtime;
-#ifdef _HAVE___UNUSED2
+#ifdef _HAVE_STAT64___UNUSED2
 	buf->__unused2 = 0;
 #endif
 	buf->st_ctime = kbuf->st_ctime;
-#ifdef _HAVE___UNUSED3
+#ifdef _HAVE_STAT64___UNUSED3
 	buf->__unused3 = 0;
 #endif
-#ifdef _HAVE___UNUSED4
+#ifdef _HAVE_STAT64___UNUSED4
 	buf->__unused4 = 0;
 #endif
-#ifdef _HAVE___UNUSED5
+#ifdef _HAVE_STAT64___UNUSED5
 	buf->__unused5 = 0;
 #endif
       }
@@ -151,23 +154,48 @@ xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf)
     {
     case _STAT_VER_LINUX:
       {
-	/* Convert current kernel version of `struct stat64' to `struct stat'.  */
+	/* Convert current kernel version of `struct stat64' to
+           `struct stat'.  */
 	buf->st_dev = kbuf->st_dev;
-#ifdef _HAVE___PAD1
+#ifdef _HAVE_STAT___PAD1
 	buf->__pad1 = 0;
 #endif
-	buf->st_ino = kbuf->st_ino;
+#ifdef _HAVE_STAT64___ST_INO
+# if __ASSUME_ST_INO_64_BIT == 0
+	if (kbuf->st_ino == 0)
+	  buf->st_ino = kbuf->__st_ino;
+	else
+# endif
+	  {
+	    buf->st_ino = kbuf->st_ino;
+	    if (sizeof (buf->st_ino) != sizeof (kbuf->__st_ino)
+		&& buf->st_ino != kbuf->st_ino)
+	      {
+		__set_errno (EOVERFLOW);
+		return -1;
+	      }
+	  }
+#else
+	buf->st_ino = kbuf->__st_ino;
+	if (sizeof (buf->st_ino) != sizeof (kbuf->__st_ino)
+	    && buf->st_ino != kbuf->st_ino)
+	  {
+	    __set_errno (EOVERFLOW);
+	    return -1;
+	  }
+#endif
 	buf->st_mode = kbuf->st_mode;
 	buf->st_nlink = kbuf->st_nlink;
 	buf->st_uid = kbuf->st_uid;
 	buf->st_gid = kbuf->st_gid;
 	buf->st_rdev = kbuf->st_rdev;
-#ifdef _HAVE___PAD2
+#ifdef _HAVE_STAT___PAD2
 	buf->__pad2 = 0;
 #endif
 	buf->st_size = kbuf->st_size;
 	/* Check for overflow.  */
-	if (buf->st_size != kbuf->st_size)
+	if (sizeof (buf->st_size) != sizeof (kbuf->st_size)
+	    && buf->st_size != kbuf->st_size)
 	  {
 	    __set_errno (EOVERFLOW);
 	    return -1;
@@ -175,27 +203,28 @@ xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf)
 	buf->st_blksize = kbuf->st_blksize;
 	buf->st_blocks = kbuf->st_blocks;
 	/* Check for overflow.  */
-	if (buf->st_blocks != kbuf->st_blocks)
+	if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks)
+	    && buf->st_blocks != kbuf->st_blocks)
 	  {
 	    __set_errno (EOVERFLOW);
 	    return -1;
 	  }
 	buf->st_atime = kbuf->st_atime;
-#ifdef _HAVE___UNUSED1
+#ifdef _HAVE_STAT___UNUSED1
 	buf->__unused1 = 0;
 #endif
 	buf->st_mtime = kbuf->st_mtime;
-#ifdef _HAVE___UNUSED2
+#ifdef _HAVE_STAT___UNUSED2
 	buf->__unused2 = 0;
 #endif
 	buf->st_ctime = kbuf->st_ctime;
-#ifdef _HAVE___UNUSED3
+#ifdef _HAVE_STAT___UNUSED3
 	buf->__unused3 = 0;
 #endif
-#ifdef _HAVE___UNUSED4
+#ifdef _HAVE_STAT___UNUSED4
 	buf->__unused4 = 0;
 #endif
-#ifdef _HAVE___UNUSED5
+#ifdef _HAVE_STAT___UNUSED5
 	buf->__unused5 = 0;
 #endif
       }