Change to using new stat and statfs system calls;
move minips to utils.

diff --git a/include/arch/alpha/klibc/archstat.h b/include/arch/alpha/klibc/archstat.h
new file mode 100644
index 0000000..23302d7
--- /dev/null
+++ b/include/arch/alpha/klibc/archstat.h
@@ -0,0 +1,26 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long	st_dev;
+	unsigned long	st_ino;
+	unsigned long	st_rdev;
+	long		st_size;
+	unsigned long	st_blocks;
+
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	st_blksize;
+	unsigned int	st_nlink;
+	unsigned int	__pad0;
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+  	long		__unused[3];
+};
+
+#endif
diff --git a/include/arch/arm/klibc/archstat.h b/include/arch/arm/klibc/archstat.h
new file mode 100644
index 0000000..42b1409
--- /dev/null
+++ b/include/arch/arm/klibc/archstat.h
@@ -0,0 +1,45 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#include <endian.h>
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ * Note: The kernel zero's the padded region because glibc might read them
+ * in the hope that the kernel has stretched to using larger sizes.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char   __pad0[4];
+
+	unsigned long	__st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char   __pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned long   __pad4;		/* Future possible st_blocks hi bits */
+	unsigned long   st_blocks;	/* Number 512-byte blocks allocated. */
+#else /* Must be little */
+	unsigned long   st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long   __pad4;		/* Future possible st_blocks hi bits */
+#endif
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/include/arch/cris/klibc/archstat.h b/include/arch/cris/klibc/archstat.h
new file mode 100644
index 0000000..1548207
--- /dev/null
+++ b/include/arch/cris/klibc/archstat.h
@@ -0,0 +1,37 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/include/arch/i386/klibc/archstat.h b/include/arch/i386/klibc/archstat.h
new file mode 100644
index 0000000..1548207
--- /dev/null
+++ b/include/arch/i386/klibc/archstat.h
@@ -0,0 +1,37 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/include/arch/ia64/klibc/archstat.h b/include/arch/ia64/klibc/archstat.h
new file mode 100644
index 0000000..9475c0b
--- /dev/null
+++ b/include/arch/ia64/klibc/archstat.h
@@ -0,0 +1,24 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long	st_dev;
+	unsigned long	st_ino;
+	unsigned long	st_nlink;
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	__pad0;
+	unsigned long	st_rdev;
+	unsigned long	st_size;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned long	st_blksize;
+	long		st_blocks;
+	unsigned long	__unused[3];
+};
+
+#endif
diff --git a/include/arch/m68k/klibc/archstat.h b/include/arch/m68k/klibc/archstat.h
new file mode 100644
index 0000000..9c0a05d
--- /dev/null
+++ b/include/arch/m68k/klibc/archstat.h
@@ -0,0 +1,37 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char	__pad1[2];
+
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[2];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/include/arch/mips/klibc/archstat.h b/include/arch/mips/klibc/archstat.h
new file mode 100644
index 0000000..58eef24
--- /dev/null
+++ b/include/arch/mips/klibc/archstat.h
@@ -0,0 +1,39 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/*
+ * This matches struct stat64 in glibc2.1, hence the absolutely insane
+ * amounts of padding around dev_t's.  The memory layout is the same as of
+ * struct stat of the 64-bit kernel.
+ */
+
+struct stat64 {
+	unsigned long	st_dev;
+	unsigned long	st_pad0[3];	/* Reserved for st_dev expansion  */
+
+	unsigned long long	st_ino;
+
+	mode_t		st_mode;
+	nlink_t		st_nlink;
+
+	uid_t		st_uid;
+	gid_t		st_gid;
+
+	unsigned long	st_rdev;
+	unsigned long	st_pad1[3];	/* Reserved for st_rdev expansion  */
+
+	long long	st_size;
+
+	struct timespec		st_atim;
+	struct timespec		st_mtim;
+	struct timespec		st_ctim;
+
+	unsigned long	st_blksize;
+	unsigned long	st_pad2;
+
+	long long	st_blocks;
+};
+
+#endif
diff --git a/include/arch/mips64/klibc/archstat.h b/include/arch/mips64/klibc/archstat.h
new file mode 100644
index 0000000..d237e3a
--- /dev/null
+++ b/include/arch/mips64/klibc/archstat.h
@@ -0,0 +1,33 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned int		st_dev;
+	unsigned int		st_pad0[3]; /* Reserved for st_dev expansion */
+
+	unsigned long		st_ino;
+
+	mode_t			st_mode;
+	nlink_t			st_nlink;
+
+	uid_t			st_uid;
+	gid_t			st_gid;
+
+	unsigned int		st_rdev;
+	unsigned int		st_pad1[3]; /* Reserved for st_rdev expansion */
+
+	off_t			st_size;
+  
+	struct timespec		st_atim;
+	struct timespec		st_mtim;
+	struct timespec		st_ctim;
+
+	unsigned int		st_blksize;
+	unsigned int		st_pad2;
+
+	unsigned long		st_blocks;
+};
+
+#endif
diff --git a/include/arch/parisc/klibc/archstat.h b/include/arch/parisc/klibc/archstat.h
new file mode 100644
index 0000000..7d28f45
--- /dev/null
+++ b/include/arch/parisc/klibc/archstat.h
@@ -0,0 +1,27 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long long	st_dev;
+	unsigned int		__pad1;
+
+	unsigned int		__st_ino;	/* Not actually filled in */
+	unsigned int		st_mode;
+	unsigned int		st_nlink;
+	unsigned int		st_uid;
+	unsigned int		st_gid;
+	unsigned long long	st_rdev;
+	unsigned int		__pad2;
+	signed long long	st_size;
+	signed int		st_blksize;
+
+	signed long long	st_blocks;
+	struct timespec		st_atim;
+	struct timespec		st_mtim;
+	struct timespec		st_ctim;
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/include/arch/ppc/klibc/archstat.h b/include/arch/ppc/klibc/archstat.h
new file mode 100644
index 0000000..1d0487b
--- /dev/null
+++ b/include/arch/ppc/klibc/archstat.h
@@ -0,0 +1,28 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1.
+ */
+struct stat {
+	unsigned long long st_dev; 	/* Device.  */
+	unsigned long long st_ino;	/* File serial number.  */
+	unsigned int st_mode;		/* File mode.  */
+	unsigned int st_nlink;		/* Link count.  */
+	unsigned int st_uid;		/* User ID of the file's owner.  */
+	unsigned int st_gid;		/* Group ID of the file's group. */
+	unsigned long long st_rdev; 	/* Device number, if device.  */
+	unsigned short int __pad2;
+	long long st_size;		/* Size of file, in bytes.  */
+	long st_blksize;		/* Optimal block size for I/O.  */
+
+	long long st_blocks;		/* Number 512-byte blocks allocated. */
+	struct timespec st_atim;	/* Time of last access.  */
+	struct timespec st_mtim;	/* Time of last modification.  */
+	struct timespec st_ctim;	/* Time of last status change.  */
+	unsigned long int __unused4;
+	unsigned long int __unused5;
+};
+
+#endif
diff --git a/include/arch/ppc64/klibc/archstat.h b/include/arch/ppc64/klibc/archstat.h
new file mode 100644
index 0000000..1a9da4f
--- /dev/null
+++ b/include/arch/ppc64/klibc/archstat.h
@@ -0,0 +1,27 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
+struct stat64 {
+	unsigned long st_dev; 		/* Device.  */
+	unsigned long st_ino;		/* File serial number.  */
+	unsigned int st_mode;		/* File mode.  */
+	unsigned int st_nlink;		/* Link count.  */
+	unsigned int st_uid;		/* User ID of the file's owner.  */
+	unsigned int st_gid;		/* Group ID of the file's group. */
+	unsigned long st_rdev; 		/* Device number, if device.  */
+	unsigned short __pad2;
+	long st_size;			/* Size of file, in bytes.  */
+	int  st_blksize;		/* Optimal block size for I/O.  */
+
+	long st_blocks;			/* Number 512-byte blocks allocated. */
+	struct timespec st_atim;	/* Time of last access.  */
+	struct timespec st_mtim;	/* Time of last modification.  */
+	struct timespec st_ctim;	/* Time of last status change.  */
+	unsigned int   __unused4;
+	unsigned int   __unused5;
+};
+
+#endif
diff --git a/include/arch/s390/klibc/archstat.h b/include/arch/s390/klibc/archstat.h
new file mode 100644
index 0000000..373c2cb
--- /dev/null
+++ b/include/arch/s390/klibc/archstat.h
@@ -0,0 +1,29 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+        unsigned long long	st_dev;
+        unsigned int    __pad1;
+#define STAT64_HAS_BROKEN_ST_INO        1
+        unsigned long   __st_ino;
+        unsigned int    st_mode;
+        unsigned int    st_nlink;
+        unsigned long   st_uid;
+        unsigned long   st_gid;
+        unsigned long long	st_rdev;
+        unsigned int    __pad3;
+        long long	st_size;
+        unsigned long   st_blksize;
+        unsigned char   __pad4[4];
+        unsigned long   __pad5;     /* future possible st_blocks high bits */
+        unsigned long   st_blocks;  /* Number 512-byte blocks allocated. */
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+        unsigned long long	st_ino;
+};
+
+#endif
diff --git a/include/arch/s390x/klibc/archstat.h b/include/arch/s390x/klibc/archstat.h
new file mode 100644
index 0000000..0de73cb
--- /dev/null
+++ b/include/arch/s390x/klibc/archstat.h
@@ -0,0 +1,24 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+        unsigned long  st_dev;
+        unsigned long  st_ino;
+        unsigned long  st_nlink;
+        unsigned int   st_mode;
+        unsigned int   st_uid;
+        unsigned int   st_gid;
+        unsigned int   __pad1;
+        unsigned long  st_rdev;
+        unsigned long  st_size;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+        unsigned long  st_blksize;
+        long           st_blocks;
+        unsigned long  __unused[3];
+};
+
+#endif
diff --git a/include/arch/sh/klibc/archstat.h b/include/arch/sh/klibc/archstat.h
new file mode 100644
index 0000000..17a0b0a
--- /dev/null
+++ b/include/arch/sh/klibc/archstat.h
@@ -0,0 +1,43 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#include <endian.h>
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+	unsigned long	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned long	__pad4;		/* Future possible st_blocks hi bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+#else /* Must be little */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* Future possible st_blocks hi bits */
+#endif
+
+	struct timespec	st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif
+
diff --git a/include/arch/sparc/klibc/archstat.h b/include/arch/sparc/klibc/archstat.h
new file mode 100644
index 0000000..0ff6878
--- /dev/null
+++ b/include/arch/sparc/klibc/archstat.h
@@ -0,0 +1,35 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long long st_dev;
+
+	unsigned long long st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+
+	unsigned long long st_rdev;
+
+	unsigned char	__pad3[8];
+
+	long long	st_size;
+	unsigned int	st_blksize;
+
+	unsigned char	__pad4[8];
+	unsigned int	st_blocks;
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned int	__unused4;
+	unsigned int	__unused5;
+};
+
+#endif
diff --git a/include/arch/sparc64/klibc/archstat.h b/include/arch/sparc64/klibc/archstat.h
new file mode 100644
index 0000000..c22905d
--- /dev/null
+++ b/include/arch/sparc64/klibc/archstat.h
@@ -0,0 +1,22 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+/* No nsec fields?! */
+struct stat {
+	unsigned   st_dev;
+	ino_t   st_ino;
+	mode_t  st_mode;
+	short   st_nlink;
+	uid_t   st_uid;
+	gid_t   st_gid;
+	unsigned   st_rdev;
+	off_t   st_size;
+	time_t  st_atime;
+	time_t  st_mtime;
+	time_t  st_ctime;
+	off_t   st_blksize;
+	off_t   st_blocks;
+	unsigned long  __unused4[2];
+};
+
+#endif
diff --git a/include/arch/x86_64/klibc/archstat.h b/include/arch/x86_64/klibc/archstat.h
new file mode 100644
index 0000000..53e141d
--- /dev/null
+++ b/include/arch/x86_64/klibc/archstat.h
@@ -0,0 +1,26 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long	st_dev;
+	unsigned long	st_ino;
+	unsigned long	st_nlink;
+
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	__pad0;
+	unsigned long	st_rdev;
+	long		st_size;
+	long		st_blksize;
+	long		st_blocks;	/* Number 512-byte blocks allocated. */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+  	long		__unused[3];
+};
+
+#endif
diff --git a/include/sys/dirent.h b/include/sys/dirent.h
index 0700f4b..eec470c 100644
--- a/include/sys/dirent.h
+++ b/include/sys/dirent.h
@@ -5,8 +5,16 @@
 #ifndef _SYS_DIRENT_H
 #define _SYS_DIRENT_H
 
-#include <sys/types.h>
-#include <linux/dirent.h>
+#include <stdint.h>
+
+/* The kernel calls this struct dirent64 */
+struct dirent {
+  uint64_t		d_ino;
+  int64_t		d_off;
+  unsigned short	d_reclen;
+  unsigned char		d_type;
+  char			d_name[256];
+};
 
 __extern int getdents(unsigned int, struct dirent *, unsigned int);
 
diff --git a/include/sys/stat.h b/include/sys/stat.h
index f7bb5aa..1bf6a75 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -7,9 +7,17 @@
 
 #include <klibc/extern.h>
 #include <sys/types.h>
-#include <asm/stat.h>
+#include <sys/time.h>		/* For struct timespec */
+#include <klibc/archstat.h>
 #include <linux/stat.h>
 
+#ifdef _STATBUF_ST_NSEC
+  /* struct stat has struct timespec instead of time_t */
+# define st_atime  st_atim.tv_sec
+# define st_mtime  st_mtim.tv_sec
+# define st_ctime  st_ctim.tv_sec
+#endif
+
 __extern int stat(const char *, struct stat *);
 __extern int fstat(int, struct stat *);
 __extern int lstat(const char *, struct stat *);
diff --git a/include/sys/statfs.h b/include/sys/statfs.h
new file mode 100644
index 0000000..53b3b5e
--- /dev/null
+++ b/include/sys/statfs.h
@@ -0,0 +1 @@
+#include <sys/vfs.h>
diff --git a/include/sys/types.h b/include/sys/types.h
index 0aaeeb1..84302b3 100644
--- a/include/sys/types.h
+++ b/include/sys/types.h
@@ -22,7 +22,8 @@
 typedef __kernel_ino_t		ino_t;
 typedef __kernel_mode_t		mode_t;
 typedef __kernel_nlink_t	nlink_t;
-typedef __kernel_off_t		off_t; /* Should become __kernel_loff_t... */
+typedef __kernel_loff_t		off_t;
+typedef __kernel_loff_t		loff_t;
 typedef __kernel_pid_t		pid_t;
 typedef __kernel_daddr_t	daddr_t;
 typedef __kernel_key_t		key_t;
@@ -32,7 +33,7 @@
 typedef __kernel_uid32_t	uid_t;
 typedef __kernel_gid32_t	gid_t;
 
-typedef __kernel_loff_t		loff_t;
+typedef __kernel_fsid_t		fsid_t;
 
 /*
  * The following typedefs are also protected by individual ifdefs for
@@ -87,37 +88,6 @@
 typedef uint64_t		u_int64_t;
 
 /*
- * transition to 64-bit sector_t, possibly making it an option...
- */
-#undef BLK_64BIT_SECTOR
-
-#ifdef BLK_64BIT_SECTOR
-typedef u64 sector_t;
-#else
-typedef unsigned long sector_t;
-#endif
-
-/*
- * The type of an index into the pagecache.  Use a #define so asm/types.h
- * can override it.
- */
-#ifndef pgoff_t
-#define pgoff_t unsigned long
-#endif
-
-/*
- * Below are truly Linux-specific types that should never collide with
- * any application/library that wants linux/types.h.
- */
-
-struct ustat {
-	__kernel_daddr_t	f_tfree;
-	__kernel_ino_t		f_tinode;
-	char			f_fname[6];
-	char			f_fpack[6];
-};
-
-/*
  * Some apps want this in <sys/types.h>
  */
 #include <sys/sysmacros.h>
diff --git a/include/sys/vfs.h b/include/sys/vfs.h
index 8c1577c..0e02c46 100644
--- a/include/sys/vfs.h
+++ b/include/sys/vfs.h
@@ -5,8 +5,46 @@
 #ifndef _SYS_VFS_H
 #define _SYS_VFS_H
 
+#include <stdint.h>
 #include <klibc/extern.h>
-#include <linux/vfs.h>
+#include <sys/types.h>
+
+/* struct statfs64 -- there seems to be two standards -
+   one for 32 and one for 64 bits, and they're incompatible... */
+
+#if BITSIZE == 32 || defined(__s390__)
+
+struct statfs {
+        uint32_t f_type;
+        uint32_t f_bsize;
+        uint64_t f_blocks;
+        uint64_t f_bfree;
+        uint64_t f_bavail;
+        uint64_t f_files;
+        uint64_t f_ffree;
+        __kernel_fsid_t f_fsid;
+        uint32_t f_namelen;
+        uint32_t f_frsize;
+        uint32_t f_spare[5];
+};
+
+#else /* BITSIZE == 64 */
+
+struct statfs {
+        uint64_t f_type;
+        uint64_t f_bsize;
+        uint64_t f_blocks;
+        uint64_t f_bfree;
+        uint64_t f_bavail;
+        uint64_t f_files;
+        uint64_t f_ffree;
+        __kernel_fsid_t f_fsid;
+        uint64_t f_namelen;
+        uint64_t f_frsize;
+        uint64_t f_spare[5];
+};
+
+#endif /* BITSIZE */
 
 __extern int statfs(const char *, struct statfs *);
 __extern int fstatfs(int, struct statfs *);
diff --git a/include/unistd.h b/include/unistd.h
index d8f6c4c..99341a5 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -81,7 +81,10 @@
 __extern int open(const char *, int, ...);
 __extern int close(int);
 __extern off_t lseek(int, off_t, int);
-__extern loff_t llseek(int, loff_t, int);
+/* off_t is 64 bits now even on 32-bit platforms; see llseek.c */
+static __inline__ off_t llseek(int __f, off_t __o, int __w) {
+  return lseek(__f, __o, __w);
+}
 __extern int dup(int);
 __extern int dup2(int, int);
 __extern int fcntl(int, int, long);
diff --git a/klibc/Makefile b/klibc/Makefile
index ffb9c51..1840f33 100644
--- a/klibc/Makefile
+++ b/klibc/Makefile
@@ -19,7 +19,7 @@
 	  execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \
 	  fork.o wait.o wait3.o waitpid.o system.o setpgrp.o getpgrp.o \
 	  printf.o vprintf.o fprintf.o vfprintf.o perror.o \
-	  fopen.o fread.o fread2.o fgetc.o fgets.o \
+	  open.o fopen.o fread.o fread2.o fgetc.o fgets.o \
 	  fwrite.o fwrite2.o fputc.o fputs.o puts.o \
 	  sleep.o usleep.o raise.o abort.o assert.o alarm.o pause.o \
 	  __signal.o sysv_signal.o bsd_signal.o siglist.o siglongjmp.o \
diff --git a/klibc/SYSCALLS.def b/klibc/SYSCALLS.def
index d0ea3cc..81aeb80 100644
--- a/klibc/SYSCALLS.def
+++ b/klibc/SYSCALLS.def
@@ -66,8 +66,8 @@
 <alpha,ia64> int umount::umount2(const char *, int)
 <!m68k> int pivot_root(const char *, const char *)
 int sync()
-int statfs(const char *, struct statfs *)
-int fstatfs(int, struct statfs *)
+int statfs64,statfs::statfs(const char *, struct statfs *)
+int fstatfs64,fstatfs::fstatfs(int, struct statfs *)
 int swapon(const char *, int)
 int swapoff(const char *)
 
@@ -89,13 +89,13 @@
 int chroot(const char *)
 int symlink(const char *, const char *)
 int readlink(const char *, char *, size_t)
-int stat(const char *, struct stat *)
-int lstat(const char *, struct stat *)
-int fstat(int, struct stat *)
-int getdents(unsigned int, struct dirent *, unsigned int)
-int chown(const char *, uid_t, gid_t)
-int fchown(int, uid_t, gid_t)
-int lchown(const char *, uid_t, gid_t)
+int stat64,stat::stat(const char *, struct stat *)
+int lstat64,lstat::lstat(const char *, struct stat *)
+int fstat64,fstat::fstat(int, struct stat *)
+int getdents64,getdents::getdents(unsigned int, struct dirent *, unsigned int)
+int chown32,chown::chown(const char *, uid_t, gid_t)
+int fchown32,fchown::fchown(int, uid_t, gid_t)
+int lchown32,lchown::lchown(const char *, uid_t, gid_t)
 int getcwd::__getcwd(char *, size_t)
 <?> int utime(const char *, const struct utimbuf *)
 <?> int utimes(const char *, const struct timeval *)
@@ -103,12 +103,13 @@
 ;
 ; I/O operations
 ;
-<!i386> int open(const char *, int, mode_t)
+<!i386,64> int open::__open(const char *, int, mode_t)
+<64> int open(const char *, int, mode_t)
 ssize_t read(int, void *, size_t)
 ssize_t write(int, const void *, size_t)
 int close(int)
-off_t lseek(int, off_t, int)
-<?32> loff_t _llseek::__llseek(int, unsigned long, unsigned long, loff_t *, int)
+<64> off_t lseek(int, off_t, int)
+<32> int _llseek::__llseek(int, unsigned long, unsigned long, off_t *, int)
 int dup(int)
 int dup2(int, int)
 int fcntl(int, int, long)
@@ -120,7 +121,9 @@
 int fdatasync,fsync::fdatasync(int)
 int readv(int, const struct iovec *, int)
 int writev(int, const struct iovec *, int)
-int ftruncate(int, off_t)
+int ftruncate64,ftruncate::ftruncate(int, off_t)
+ssize_t pread64,pread::pread(int, void *, size_t, off_t)
+ssize_t pwrite64,pread::pread(int, void *, size_t, off_t)
 
 ;
 ; Signal operations
@@ -157,9 +160,9 @@
 int msync(const void *, size_t, int)
 int mprotect(const void *, size_t, int)
 #if (BITSIZE == 32 && defined(__NR_mmap2)) || (BITSIZE == 64 && !defined(__NR_mmap))
-void * mmap2::__mmap2(void *, size_t, int, int, int, size_t)
+void * mmap2::__mmap2(void *, size_t, int, int, int, long)
 #else
-void * mmap(void *, size_t, int, int, int, off_t)
+void * mmap(void *, size_t, int, int, int, long)
 #endif
 
 ;
diff --git a/klibc/arch/alpha/include/klibc/archstat.h b/klibc/arch/alpha/include/klibc/archstat.h
new file mode 100644
index 0000000..23302d7
--- /dev/null
+++ b/klibc/arch/alpha/include/klibc/archstat.h
@@ -0,0 +1,26 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long	st_dev;
+	unsigned long	st_ino;
+	unsigned long	st_rdev;
+	long		st_size;
+	unsigned long	st_blocks;
+
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	st_blksize;
+	unsigned int	st_nlink;
+	unsigned int	__pad0;
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+  	long		__unused[3];
+};
+
+#endif
diff --git a/klibc/arch/arm/include/klibc/archstat.h b/klibc/arch/arm/include/klibc/archstat.h
new file mode 100644
index 0000000..42b1409
--- /dev/null
+++ b/klibc/arch/arm/include/klibc/archstat.h
@@ -0,0 +1,45 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#include <endian.h>
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ * Note: The kernel zero's the padded region because glibc might read them
+ * in the hope that the kernel has stretched to using larger sizes.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char   __pad0[4];
+
+	unsigned long	__st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char   __pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned long   __pad4;		/* Future possible st_blocks hi bits */
+	unsigned long   st_blocks;	/* Number 512-byte blocks allocated. */
+#else /* Must be little */
+	unsigned long   st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long   __pad4;		/* Future possible st_blocks hi bits */
+#endif
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/klibc/arch/cris/include/klibc/archstat.h b/klibc/arch/cris/include/klibc/archstat.h
new file mode 100644
index 0000000..1548207
--- /dev/null
+++ b/klibc/arch/cris/include/klibc/archstat.h
@@ -0,0 +1,37 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/klibc/arch/i386/include/klibc/archstat.h b/klibc/arch/i386/include/klibc/archstat.h
new file mode 100644
index 0000000..1548207
--- /dev/null
+++ b/klibc/arch/i386/include/klibc/archstat.h
@@ -0,0 +1,37 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/klibc/arch/ia64/include/klibc/archstat.h b/klibc/arch/ia64/include/klibc/archstat.h
new file mode 100644
index 0000000..9475c0b
--- /dev/null
+++ b/klibc/arch/ia64/include/klibc/archstat.h
@@ -0,0 +1,24 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long	st_dev;
+	unsigned long	st_ino;
+	unsigned long	st_nlink;
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	__pad0;
+	unsigned long	st_rdev;
+	unsigned long	st_size;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned long	st_blksize;
+	long		st_blocks;
+	unsigned long	__unused[3];
+};
+
+#endif
diff --git a/klibc/arch/m68k/include/klibc/archstat.h b/klibc/arch/m68k/include/klibc/archstat.h
new file mode 100644
index 0000000..9c0a05d
--- /dev/null
+++ b/klibc/arch/m68k/include/klibc/archstat.h
@@ -0,0 +1,37 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+	unsigned long long	st_dev;
+	unsigned char	__pad1[2];
+
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[2];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/klibc/arch/mips/include/klibc/archstat.h b/klibc/arch/mips/include/klibc/archstat.h
new file mode 100644
index 0000000..58eef24
--- /dev/null
+++ b/klibc/arch/mips/include/klibc/archstat.h
@@ -0,0 +1,39 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/*
+ * This matches struct stat64 in glibc2.1, hence the absolutely insane
+ * amounts of padding around dev_t's.  The memory layout is the same as of
+ * struct stat of the 64-bit kernel.
+ */
+
+struct stat64 {
+	unsigned long	st_dev;
+	unsigned long	st_pad0[3];	/* Reserved for st_dev expansion  */
+
+	unsigned long long	st_ino;
+
+	mode_t		st_mode;
+	nlink_t		st_nlink;
+
+	uid_t		st_uid;
+	gid_t		st_gid;
+
+	unsigned long	st_rdev;
+	unsigned long	st_pad1[3];	/* Reserved for st_rdev expansion  */
+
+	long long	st_size;
+
+	struct timespec		st_atim;
+	struct timespec		st_mtim;
+	struct timespec		st_ctim;
+
+	unsigned long	st_blksize;
+	unsigned long	st_pad2;
+
+	long long	st_blocks;
+};
+
+#endif
diff --git a/klibc/arch/mips64/include/klibc/archstat.h b/klibc/arch/mips64/include/klibc/archstat.h
new file mode 100644
index 0000000..d237e3a
--- /dev/null
+++ b/klibc/arch/mips64/include/klibc/archstat.h
@@ -0,0 +1,33 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned int		st_dev;
+	unsigned int		st_pad0[3]; /* Reserved for st_dev expansion */
+
+	unsigned long		st_ino;
+
+	mode_t			st_mode;
+	nlink_t			st_nlink;
+
+	uid_t			st_uid;
+	gid_t			st_gid;
+
+	unsigned int		st_rdev;
+	unsigned int		st_pad1[3]; /* Reserved for st_rdev expansion */
+
+	off_t			st_size;
+  
+	struct timespec		st_atim;
+	struct timespec		st_mtim;
+	struct timespec		st_ctim;
+
+	unsigned int		st_blksize;
+	unsigned int		st_pad2;
+
+	unsigned long		st_blocks;
+};
+
+#endif
diff --git a/klibc/arch/parisc/include/klibc/archstat.h b/klibc/arch/parisc/include/klibc/archstat.h
new file mode 100644
index 0000000..7d28f45
--- /dev/null
+++ b/klibc/arch/parisc/include/klibc/archstat.h
@@ -0,0 +1,27 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long long	st_dev;
+	unsigned int		__pad1;
+
+	unsigned int		__st_ino;	/* Not actually filled in */
+	unsigned int		st_mode;
+	unsigned int		st_nlink;
+	unsigned int		st_uid;
+	unsigned int		st_gid;
+	unsigned long long	st_rdev;
+	unsigned int		__pad2;
+	signed long long	st_size;
+	signed int		st_blksize;
+
+	signed long long	st_blocks;
+	struct timespec		st_atim;
+	struct timespec		st_mtim;
+	struct timespec		st_ctim;
+	unsigned long long	st_ino;
+};
+
+#endif
diff --git a/klibc/arch/ppc/include/klibc/archstat.h b/klibc/arch/ppc/include/klibc/archstat.h
new file mode 100644
index 0000000..1d0487b
--- /dev/null
+++ b/klibc/arch/ppc/include/klibc/archstat.h
@@ -0,0 +1,28 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1.
+ */
+struct stat {
+	unsigned long long st_dev; 	/* Device.  */
+	unsigned long long st_ino;	/* File serial number.  */
+	unsigned int st_mode;		/* File mode.  */
+	unsigned int st_nlink;		/* Link count.  */
+	unsigned int st_uid;		/* User ID of the file's owner.  */
+	unsigned int st_gid;		/* Group ID of the file's group. */
+	unsigned long long st_rdev; 	/* Device number, if device.  */
+	unsigned short int __pad2;
+	long long st_size;		/* Size of file, in bytes.  */
+	long st_blksize;		/* Optimal block size for I/O.  */
+
+	long long st_blocks;		/* Number 512-byte blocks allocated. */
+	struct timespec st_atim;	/* Time of last access.  */
+	struct timespec st_mtim;	/* Time of last modification.  */
+	struct timespec st_ctim;	/* Time of last status change.  */
+	unsigned long int __unused4;
+	unsigned long int __unused5;
+};
+
+#endif
diff --git a/klibc/arch/ppc64/include/klibc/archstat.h b/klibc/arch/ppc64/include/klibc/archstat.h
new file mode 100644
index 0000000..1a9da4f
--- /dev/null
+++ b/klibc/arch/ppc64/include/klibc/archstat.h
@@ -0,0 +1,27 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
+struct stat64 {
+	unsigned long st_dev; 		/* Device.  */
+	unsigned long st_ino;		/* File serial number.  */
+	unsigned int st_mode;		/* File mode.  */
+	unsigned int st_nlink;		/* Link count.  */
+	unsigned int st_uid;		/* User ID of the file's owner.  */
+	unsigned int st_gid;		/* Group ID of the file's group. */
+	unsigned long st_rdev; 		/* Device number, if device.  */
+	unsigned short __pad2;
+	long st_size;			/* Size of file, in bytes.  */
+	int  st_blksize;		/* Optimal block size for I/O.  */
+
+	long st_blocks;			/* Number 512-byte blocks allocated. */
+	struct timespec st_atim;	/* Time of last access.  */
+	struct timespec st_mtim;	/* Time of last modification.  */
+	struct timespec st_ctim;	/* Time of last status change.  */
+	unsigned int   __unused4;
+	unsigned int   __unused5;
+};
+
+#endif
diff --git a/klibc/arch/s390/include/klibc/archstat.h b/klibc/arch/s390/include/klibc/archstat.h
new file mode 100644
index 0000000..373c2cb
--- /dev/null
+++ b/klibc/arch/s390/include/klibc/archstat.h
@@ -0,0 +1,29 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+        unsigned long long	st_dev;
+        unsigned int    __pad1;
+#define STAT64_HAS_BROKEN_ST_INO        1
+        unsigned long   __st_ino;
+        unsigned int    st_mode;
+        unsigned int    st_nlink;
+        unsigned long   st_uid;
+        unsigned long   st_gid;
+        unsigned long long	st_rdev;
+        unsigned int    __pad3;
+        long long	st_size;
+        unsigned long   st_blksize;
+        unsigned char   __pad4[4];
+        unsigned long   __pad5;     /* future possible st_blocks high bits */
+        unsigned long   st_blocks;  /* Number 512-byte blocks allocated. */
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+        unsigned long long	st_ino;
+};
+
+#endif
diff --git a/klibc/arch/s390x/include/klibc/archstat.h b/klibc/arch/s390x/include/klibc/archstat.h
new file mode 100644
index 0000000..0de73cb
--- /dev/null
+++ b/klibc/arch/s390x/include/klibc/archstat.h
@@ -0,0 +1,24 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+        unsigned long  st_dev;
+        unsigned long  st_ino;
+        unsigned long  st_nlink;
+        unsigned int   st_mode;
+        unsigned int   st_uid;
+        unsigned int   st_gid;
+        unsigned int   __pad1;
+        unsigned long  st_rdev;
+        unsigned long  st_size;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+        unsigned long  st_blksize;
+        long           st_blocks;
+        unsigned long  __unused[3];
+};
+
+#endif
diff --git a/klibc/arch/sh/include/klibc/archstat.h b/klibc/arch/sh/include/klibc/archstat.h
new file mode 100644
index 0000000..17a0b0a
--- /dev/null
+++ b/klibc/arch/sh/include/klibc/archstat.h
@@ -0,0 +1,43 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#include <endian.h>
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+	unsigned long	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned long	__pad4;		/* Future possible st_blocks hi bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+#else /* Must be little */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* Future possible st_blocks hi bits */
+#endif
+
+	struct timespec	st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+};
+
+#endif
+
diff --git a/klibc/arch/sparc/include/klibc/archstat.h b/klibc/arch/sparc/include/klibc/archstat.h
new file mode 100644
index 0000000..0ff6878
--- /dev/null
+++ b/klibc/arch/sparc/include/klibc/archstat.h
@@ -0,0 +1,35 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long long st_dev;
+
+	unsigned long long st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+
+	unsigned long long st_rdev;
+
+	unsigned char	__pad3[8];
+
+	long long	st_size;
+	unsigned int	st_blksize;
+
+	unsigned char	__pad4[8];
+	unsigned int	st_blocks;
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+
+	unsigned int	__unused4;
+	unsigned int	__unused5;
+};
+
+#endif
diff --git a/klibc/arch/sparc64/include/klibc/archstat.h b/klibc/arch/sparc64/include/klibc/archstat.h
new file mode 100644
index 0000000..c22905d
--- /dev/null
+++ b/klibc/arch/sparc64/include/klibc/archstat.h
@@ -0,0 +1,22 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+/* No nsec fields?! */
+struct stat {
+	unsigned   st_dev;
+	ino_t   st_ino;
+	mode_t  st_mode;
+	short   st_nlink;
+	uid_t   st_uid;
+	gid_t   st_gid;
+	unsigned   st_rdev;
+	off_t   st_size;
+	time_t  st_atime;
+	time_t  st_mtime;
+	time_t  st_ctime;
+	off_t   st_blksize;
+	off_t   st_blocks;
+	unsigned long  __unused4[2];
+};
+
+#endif
diff --git a/klibc/arch/x86_64/include/klibc/archstat.h b/klibc/arch/x86_64/include/klibc/archstat.h
new file mode 100644
index 0000000..53e141d
--- /dev/null
+++ b/klibc/arch/x86_64/include/klibc/archstat.h
@@ -0,0 +1,26 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+struct stat {
+	unsigned long	st_dev;
+	unsigned long	st_ino;
+	unsigned long	st_nlink;
+
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	__pad0;
+	unsigned long	st_rdev;
+	long		st_size;
+	long		st_blksize;
+	long		st_blocks;	/* Number 512-byte blocks allocated. */
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+  	long		__unused[3];
+};
+
+#endif
diff --git a/klibc/include/sys/dirent.h b/klibc/include/sys/dirent.h
index 0700f4b..eec470c 100644
--- a/klibc/include/sys/dirent.h
+++ b/klibc/include/sys/dirent.h
@@ -5,8 +5,16 @@
 #ifndef _SYS_DIRENT_H
 #define _SYS_DIRENT_H
 
-#include <sys/types.h>
-#include <linux/dirent.h>
+#include <stdint.h>
+
+/* The kernel calls this struct dirent64 */
+struct dirent {
+  uint64_t		d_ino;
+  int64_t		d_off;
+  unsigned short	d_reclen;
+  unsigned char		d_type;
+  char			d_name[256];
+};
 
 __extern int getdents(unsigned int, struct dirent *, unsigned int);
 
diff --git a/klibc/include/sys/stat.h b/klibc/include/sys/stat.h
index f7bb5aa..1bf6a75 100644
--- a/klibc/include/sys/stat.h
+++ b/klibc/include/sys/stat.h
@@ -7,9 +7,17 @@
 
 #include <klibc/extern.h>
 #include <sys/types.h>
-#include <asm/stat.h>
+#include <sys/time.h>		/* For struct timespec */
+#include <klibc/archstat.h>
 #include <linux/stat.h>
 
+#ifdef _STATBUF_ST_NSEC
+  /* struct stat has struct timespec instead of time_t */
+# define st_atime  st_atim.tv_sec
+# define st_mtime  st_mtim.tv_sec
+# define st_ctime  st_ctim.tv_sec
+#endif
+
 __extern int stat(const char *, struct stat *);
 __extern int fstat(int, struct stat *);
 __extern int lstat(const char *, struct stat *);
diff --git a/klibc/include/sys/statfs.h b/klibc/include/sys/statfs.h
new file mode 100644
index 0000000..53b3b5e
--- /dev/null
+++ b/klibc/include/sys/statfs.h
@@ -0,0 +1 @@
+#include <sys/vfs.h>
diff --git a/klibc/include/sys/types.h b/klibc/include/sys/types.h
index 0aaeeb1..84302b3 100644
--- a/klibc/include/sys/types.h
+++ b/klibc/include/sys/types.h
@@ -22,7 +22,8 @@
 typedef __kernel_ino_t		ino_t;
 typedef __kernel_mode_t		mode_t;
 typedef __kernel_nlink_t	nlink_t;
-typedef __kernel_off_t		off_t; /* Should become __kernel_loff_t... */
+typedef __kernel_loff_t		off_t;
+typedef __kernel_loff_t		loff_t;
 typedef __kernel_pid_t		pid_t;
 typedef __kernel_daddr_t	daddr_t;
 typedef __kernel_key_t		key_t;
@@ -32,7 +33,7 @@
 typedef __kernel_uid32_t	uid_t;
 typedef __kernel_gid32_t	gid_t;
 
-typedef __kernel_loff_t		loff_t;
+typedef __kernel_fsid_t		fsid_t;
 
 /*
  * The following typedefs are also protected by individual ifdefs for
@@ -87,37 +88,6 @@
 typedef uint64_t		u_int64_t;
 
 /*
- * transition to 64-bit sector_t, possibly making it an option...
- */
-#undef BLK_64BIT_SECTOR
-
-#ifdef BLK_64BIT_SECTOR
-typedef u64 sector_t;
-#else
-typedef unsigned long sector_t;
-#endif
-
-/*
- * The type of an index into the pagecache.  Use a #define so asm/types.h
- * can override it.
- */
-#ifndef pgoff_t
-#define pgoff_t unsigned long
-#endif
-
-/*
- * Below are truly Linux-specific types that should never collide with
- * any application/library that wants linux/types.h.
- */
-
-struct ustat {
-	__kernel_daddr_t	f_tfree;
-	__kernel_ino_t		f_tinode;
-	char			f_fname[6];
-	char			f_fpack[6];
-};
-
-/*
  * Some apps want this in <sys/types.h>
  */
 #include <sys/sysmacros.h>
diff --git a/klibc/include/sys/vfs.h b/klibc/include/sys/vfs.h
index 8c1577c..0e02c46 100644
--- a/klibc/include/sys/vfs.h
+++ b/klibc/include/sys/vfs.h
@@ -5,8 +5,46 @@
 #ifndef _SYS_VFS_H
 #define _SYS_VFS_H
 
+#include <stdint.h>
 #include <klibc/extern.h>
-#include <linux/vfs.h>
+#include <sys/types.h>
+
+/* struct statfs64 -- there seems to be two standards -
+   one for 32 and one for 64 bits, and they're incompatible... */
+
+#if BITSIZE == 32 || defined(__s390__)
+
+struct statfs {
+        uint32_t f_type;
+        uint32_t f_bsize;
+        uint64_t f_blocks;
+        uint64_t f_bfree;
+        uint64_t f_bavail;
+        uint64_t f_files;
+        uint64_t f_ffree;
+        __kernel_fsid_t f_fsid;
+        uint32_t f_namelen;
+        uint32_t f_frsize;
+        uint32_t f_spare[5];
+};
+
+#else /* BITSIZE == 64 */
+
+struct statfs {
+        uint64_t f_type;
+        uint64_t f_bsize;
+        uint64_t f_blocks;
+        uint64_t f_bfree;
+        uint64_t f_bavail;
+        uint64_t f_files;
+        uint64_t f_ffree;
+        __kernel_fsid_t f_fsid;
+        uint64_t f_namelen;
+        uint64_t f_frsize;
+        uint64_t f_spare[5];
+};
+
+#endif /* BITSIZE */
 
 __extern int statfs(const char *, struct statfs *);
 __extern int fstatfs(int, struct statfs *);
diff --git a/klibc/include/unistd.h b/klibc/include/unistd.h
index d8f6c4c..99341a5 100644
--- a/klibc/include/unistd.h
+++ b/klibc/include/unistd.h
@@ -81,7 +81,10 @@
 __extern int open(const char *, int, ...);
 __extern int close(int);
 __extern off_t lseek(int, off_t, int);
-__extern loff_t llseek(int, loff_t, int);
+/* off_t is 64 bits now even on 32-bit platforms; see llseek.c */
+static __inline__ off_t llseek(int __f, off_t __o, int __w) {
+  return lseek(__f, __o, __w);
+}
 __extern int dup(int);
 __extern int dup2(int, int);
 __extern int fcntl(int, int, long);
diff --git a/klibc/llseek.c b/klibc/llseek.c
index f938714..2102a50 100644
--- a/klibc/llseek.c
+++ b/klibc/llseek.c
@@ -1,10 +1,10 @@
 /*
  * llseek.c
  *
- * On 32-bit platforms, we need llseek() as well as lseek() to be
- * able to handle large disks.  llseek() isn't just a normal syscall
- * which takes a 64-bit argument; it needs to return a 64-bit value
- * and so takes an extra pointer.
+ * On 32-bit platforms, we need to use the _llseek() system call
+ * rather than lseek(), to be able to handle large disks.  _llseek()
+ * isn't just a normal syscall which takes a 64-bit argument; it needs
+ * to return a 64-bit value and so takes an extra pointer.
  */
 
 #include <unistd.h>
@@ -12,24 +12,17 @@
 
 #if BITSIZE == 32
 
-extern int __llseek(int fd, unsigned long hi, unsigned long lo, loff_t *res, int whence);
+extern int __llseek(int fd, unsigned long hi, unsigned long lo, off_t *res, int whence);
 
-loff_t llseek(int fd, loff_t offset, int whence)
+off_t lseek(int fd, off_t offset, int whence)
 {
-  loff_t result;
+  off_t result;
   int rv;
 
-  rv = __llseek(fd, (unsigned long)(offset >> 32),
-		(unsigned long)offset, &result, whence);
+  rv = __llseek(fd, (unsigned long)(offset >> 32), (unsigned long)offset,
+		&result, whence);
   
-  return rv ? (loff_t)-1 : result;
-}
-
-#else
-
-loff_t llseek(int fd, loff_t offset, int whence)
-{
-  return lseek(fd, offset, whence);
+  return rv ? (off_t)-1 : result;
 }
 
 #endif
diff --git a/klibc/open.c b/klibc/open.c
new file mode 100644
index 0000000..e1d1233
--- /dev/null
+++ b/klibc/open.c
@@ -0,0 +1,20 @@
+/*
+ * open.c
+ *
+ * On 32-bit platforms we need to pass O_LARGEFILE to the open()
+ * system call, to indicate that we're 64-bit safe.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#if BITSIZE == 32 && !defined(__i386__)
+
+extern int __open(const char *, int, mode_t);
+
+int open(const char *pathname, int flags, mode_t mode)
+{
+  return __open(pathname, flags|O_LARGEFILE, mode);
+}
+
+#endif
diff --git a/utils/Makefile b/utils/Makefile
index d3e1809..fcb4304 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -6,7 +6,7 @@
 CFLAGS       = $(MAKEDEPS) $(OPTFLAGS) $(REQFLAGS) -W -Wall
 LIBS         = $(KLIBC) $(LIBGCC)
 PROGS       := chroot dd fstype mkdir mkfifo mount pivot_root umount \
-	       true false sleep ln nuke
+	       true false sleep ln nuke minips
 STATICPROGS := $(patsubst %,static/%,$(PROGS))
 SHAREDPROGS := $(patsubst %,shared/%,$(PROGS))
 LIBOBJS	     = file_mode.o
diff --git a/klibc/tests/minips.c b/utils/minips.c
similarity index 100%
rename from klibc/tests/minips.c
rename to utils/minips.c