From: Peter Chubb <peter@chubb.wattle.id.au>

Add two new system calls, statfs64 and fstatfs64.
   
- Use a common interface (vfs_statfs) with the rest of the kernel,

- convert to 32-bit at (f)statfs time.

- New field f_frsize gives underlying fragment size for the filesystem. 
  (Solaris has this, and the Open Group describe it).

The new system calls take a size_t argument, which is the size of the
structure to be filled in (as requested by Ben LaHaise), to `futureproof' the
interface.



 arch/alpha/kernel/osf_sys.c   |    7 +-
 arch/i386/kernel/entry.S      |    3 -
 arch/ia64/ia32/ia32_entry.S   |   22 ++++++++
 arch/ia64/kernel/entry.S      |    4 -
 arch/ia64/kernel/ivt.S        |    2 
 fs/adfs/super.c               |    4 -
 fs/affs/super.c               |    4 -
 fs/befs/linuxvfs.c            |    4 -
 fs/bfs/inode.c                |    2 
 fs/cifs/cifsfs.c              |    2 
 fs/coda/inode.c               |    4 -
 fs/coda/upcall.c              |    2 
 fs/compat.c                   |   16 ++++-
 fs/cramfs/inode.c             |    2 
 fs/efs/super.c                |    2 
 fs/ext2/super.c               |    4 -
 fs/ext3/super.c               |    2 
 fs/fat/inode.c                |    2 
 fs/freevxfs/vxfs_super.c      |    4 -
 fs/hfs/super.c                |    4 -
 fs/hpfs/hpfs_fn.h             |    2 
 fs/hpfs/super.c               |    2 
 fs/intermezzo/intermezzo_fs.h |    2 
 fs/isofs/inode.c              |    4 -
 fs/jfs/super.c                |    2 
 fs/libfs.c                    |    2 
 fs/minix/inode.c              |    4 -
 fs/ncpfs/inode.c              |    4 -
 fs/nfs/inode.c                |    4 -
 fs/nfsd/nfs3xdr.c             |    2 
 fs/nfsd/nfs4xdr.c             |    2 
 fs/nfsd/nfsxdr.c              |    2 
 fs/nfsd/vfs.c                 |    2 
 fs/ntfs/super.c               |    2 
 fs/open.c                     |  115 +++++++++++++++++++++++++++++++++++++++---
 fs/qnx4/inode.c               |    4 -
 fs/reiserfs/super.c           |    4 -
 fs/romfs/inode.c              |    2 
 fs/smbfs/inode.c              |    4 -
 fs/smbfs/proc.c               |    2 
 fs/smbfs/proto.h              |    2 
 fs/super.c                    |    2 
 fs/sysv/inode.c               |    2 
 fs/udf/super.c                |    4 -
 fs/ufs/super.c                |    6 +-
 fs/xfs/linux/xfs_super.c      |    4 -
 fs/xfs/linux/xfs_vfs.c        |    2 
 fs/xfs/linux/xfs_vfs.h        |    6 +-
 fs/xfs/xfs_vfsops.c           |    4 -
 include/asm-alpha/statfs.h    |   21 -------
 include/asm-arm/statfs.h      |   21 -------
 include/asm-cris/statfs.h     |   21 -------
 include/asm-generic/statfs.h  |   37 +++++++++++++
 include/asm-h8300/statfs.h    |   21 -------
 include/asm-i386/statfs.h     |   21 -------
 include/asm-i386/unistd.h     |    4 +
 include/asm-ia64/compat.h     |    3 -
 include/asm-ia64/statfs.h     |   27 +++++++--
 include/asm-ia64/unistd.h     |    4 +
 include/asm-m68k/statfs.h     |   21 -------
 include/asm-parisc/compat.h   |    3 -
 include/asm-parisc/statfs.h   |   21 +++++++
 include/asm-ppc/statfs.h      |   22 --------
 include/asm-ppc64/compat.h    |    3 -
 include/asm-ppc64/statfs.h    |   20 ++++++-
 include/asm-sparc/statfs.h    |   21 -------
 include/asm-sparc64/statfs.h  |   17 +++++-
 include/asm-x86_64/compat.h   |    3 -
 include/asm-x86_64/statfs.h   |   21 +++++++
 include/linux/coda_psdev.h    |    2 
 include/linux/efs_fs.h        |    2 
 include/linux/ext3_fs.h       |    2 
 include/linux/fs.h            |    8 +-
 include/linux/msdos_fs.h      |    2 
 include/linux/nfsd/nfsd.h     |    2 
 include/linux/nfsd/xdr.h      |    2 
 include/linux/nfsd/xdr3.h     |    2 
 include/linux/statfs.h        |   22 ++++++++
 include/linux/vfs.h           |    2 
 kernel/acct.c                 |   14 ++++-
 mm/shmem.c                    |    2 
 81 files changed, 416 insertions(+), 273 deletions(-)

diff -puN arch/alpha/kernel/osf_sys.c~statfs64-3 arch/alpha/kernel/osf_sys.c
--- 25/arch/alpha/kernel/osf_sys.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/arch/alpha/kernel/osf_sys.c	2003-06-16 00:51:16.000000000 -0700
@@ -218,15 +218,14 @@ struct osf_statfs {
 } *osf_stat;
 
 static int
-linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat,
+linux_to_osf_statfs(struct kstatfs *linux_stat, struct osf_statfs *osf_stat,
 		    unsigned long bufsiz)
 {
 	struct osf_statfs tmp_stat;
 
 	tmp_stat.f_type = linux_stat->f_type;
 	tmp_stat.f_flags = 0;	/* mount flags */
-	/* Linux doesn't provide a "fundamental filesystem block size": */
-	tmp_stat.f_fsize = linux_stat->f_bsize;
+	tmp_stat.f_fsize = linux_stat->f_frsize;
 	tmp_stat.f_bsize = linux_stat->f_bsize;
 	tmp_stat.f_blocks = linux_stat->f_blocks;
 	tmp_stat.f_bfree = linux_stat->f_bfree;
@@ -243,7 +242,7 @@ static int
 do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer,
 	      unsigned long bufsiz)
 {
-	struct statfs linux_stat;
+	struct kstatfs linux_stat;
 	int error = vfs_statfs(dentry->d_inode->i_sb, &linux_stat);
 	if (!error)
 		error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);
diff -puN arch/i386/kernel/entry.S~statfs64-3 arch/i386/kernel/entry.S
--- 25/arch/i386/kernel/entry.S~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/arch/i386/kernel/entry.S	2003-06-16 00:51:16.000000000 -0700
@@ -900,6 +900,7 @@ ENTRY(sys_call_table)
  	.long sys_clock_gettime		/* 265 */
  	.long sys_clock_getres
  	.long sys_clock_nanosleep
- 
+	.long sys_statfs64
+	.long sys_fstatfs64	
  
 nr_syscalls=(.-sys_call_table)/4
diff -puN arch/ia64/ia32/ia32_entry.S~statfs64-3 arch/ia64/ia32/ia32_entry.S
--- 25/arch/ia64/ia32/ia32_entry.S~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/arch/ia64/ia32/ia32_entry.S	2003-06-16 00:51:16.000000000 -0700
@@ -448,6 +448,28 @@ ia32_syscall_table:
 	data8 sys_ni_syscall
 	data8 sys_ni_syscall
 	data8 sys_ni_syscall
+	data8 sys_ni_syscall	/* 250 */
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall	/*255*/
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall	/* 260 */
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall	/* 265 */
+	data8 sys_ni_syscall
+	data8 sys_ni_syscall
+	data8 sys_statfs64
+	data8 sys_fstatfs64
+	data8 sys_ni_syscall
+	
 	/*
 	 *  CAUTION: If any system calls are added beyond this point
 	 *	then the check in `arch/ia64/kernel/ivt.S' will have
diff -puN arch/ia64/kernel/entry.S~statfs64-3 arch/ia64/kernel/entry.S
--- 25/arch/ia64/kernel/entry.S~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/arch/ia64/kernel/entry.S	2003-06-16 00:51:16.000000000 -0700
@@ -1291,8 +1291,8 @@ sys_call_table:
 	data8 sys_clock_gettime
 	data8 sys_clock_getres			// 1255
 	data8 sys_clock_nanosleep
-	data8 ia64_ni_syscall
-	data8 ia64_ni_syscall
+	data8 sys_fstatfs64
+	data8 sys_statfs64
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall			// 1260
 	data8 ia64_ni_syscall
diff -puN arch/ia64/kernel/ivt.S~statfs64-3 arch/ia64/kernel/ivt.S
--- 25/arch/ia64/kernel/ivt.S~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/arch/ia64/kernel/ivt.S	2003-06-16 00:51:16.000000000 -0700
@@ -848,7 +848,7 @@ ENTRY(dispatch_to_ia32_handler)
 	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
 	;;
 	ld4 r8=[r14],8		// r8 == eax (syscall number)
-	mov r15=250		// number of entries in ia32 system call table
+	mov r15=270		// number of entries in ia32 system call table
 	;;
 	cmp.ltu.unc p6,p7=r8,r15
 	ld4 out1=[r14],8	// r9 == ecx
diff -puN fs/adfs/super.c~statfs64-3 fs/adfs/super.c
--- 25/fs/adfs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/adfs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -189,7 +189,7 @@ static int adfs_remount(struct super_blo
 	return parse_options(sb, data);
 }
 
-static int adfs_statfs(struct super_block *sb, struct statfs *buf)
+static int adfs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct adfs_sb_info *asb = ADFS_SB(sb);
 
@@ -200,7 +200,7 @@ static int adfs_statfs(struct super_bloc
 	buf->f_files   = asb->s_ids_per_zone * asb->s_map_size;
 	buf->f_bavail  =
 	buf->f_bfree   = adfs_map_free(sb);
-	buf->f_ffree   = buf->f_bfree * buf->f_files / buf->f_blocks;
+	buf->f_ffree   = (long)(buf->f_bfree * buf->f_files) / (long)buf->f_blocks;
 
 	return 0;
 }
diff -puN fs/affs/super.c~statfs64-3 fs/affs/super.c
--- 25/fs/affs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/affs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -33,7 +33,7 @@
 
 extern struct timezone sys_tz;
 
-static int affs_statfs(struct super_block *sb, struct statfs *buf);
+static int affs_statfs(struct super_block *sb, struct kstatfs *buf);
 static int affs_remount (struct super_block *sb, int *flags, char *data);
 
 static void
@@ -524,7 +524,7 @@ affs_remount(struct super_block *sb, int
 }
 
 static int
-affs_statfs(struct super_block *sb, struct statfs *buf)
+affs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	int		 free;
 
diff -puN fs/befs/linuxvfs.c~statfs64-3 fs/befs/linuxvfs.c
--- 25/fs/befs/linuxvfs.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/befs/linuxvfs.c	2003-06-16 00:51:16.000000000 -0700
@@ -47,7 +47,7 @@ static int befs_nls2utf(struct super_blo
 			char **out, int *out_len);
 static void befs_put_super(struct super_block *);
 static int befs_remount(struct super_block *, int *, char *);
-static int befs_statfs(struct super_block *, struct statfs *);
+static int befs_statfs(struct super_block *, struct kstatfs *);
 static int parse_options(char *, befs_mount_options *);
 
 static const struct super_operations befs_sops = {
@@ -896,7 +896,7 @@ befs_remount(struct super_block *sb, int
 }
 
 static int
-befs_statfs(struct super_block *sb, struct statfs *buf)
+befs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 
 	befs_debug(sb, "---> befs_statfs()");
diff -puN fs/bfs/inode.c~statfs64-3 fs/bfs/inode.c
--- 25/fs/bfs/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/bfs/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -191,7 +191,7 @@ static void bfs_put_super(struct super_b
 	s->s_fs_info = NULL;
 }
 
-static int bfs_statfs(struct super_block *s, struct statfs *buf)
+static int bfs_statfs(struct super_block *s, struct kstatfs *buf)
 {
 	struct bfs_sb_info *info = BFS_SB(s);
 	buf->f_type = BFS_MAGIC;
diff -puN fs/cifs/cifsfs.c~statfs64-3 fs/cifs/cifsfs.c
--- 25/fs/cifs/cifsfs.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/cifs/cifsfs.c	2003-06-16 00:51:16.000000000 -0700
@@ -143,7 +143,7 @@ cifs_put_super(struct super_block *sb)
 }
 
 int
-cifs_statfs(struct super_block *sb, struct statfs *buf)
+cifs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	int xid, rc;
 	struct cifs_sb_info *cifs_sb;
diff -puN fs/coda/inode.c~statfs64-3 fs/coda/inode.c
--- 25/fs/coda/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/coda/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -34,7 +34,7 @@
 /* VFS super_block ops */
 static void coda_clear_inode(struct inode *);
 static void coda_put_super(struct super_block *);
-static int coda_statfs(struct super_block *sb, struct statfs *buf);
+static int coda_statfs(struct super_block *sb, struct kstatfs *buf);
 
 static kmem_cache_t * coda_inode_cachep;
 
@@ -273,7 +273,7 @@ struct inode_operations coda_file_inode_
 	.setattr	= coda_setattr,
 };
 
-static int coda_statfs(struct super_block *sb, struct statfs *buf)
+static int coda_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	int error;
 	
diff -puN fs/coda/upcall.c~statfs64-3 fs/coda/upcall.c
--- 25/fs/coda/upcall.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/coda/upcall.c	2003-06-16 00:51:16.000000000 -0700
@@ -585,7 +585,7 @@ int venus_pioctl(struct super_block *sb,
 	return error;
 }
 
-int venus_statfs(struct super_block *sb, struct statfs *sfs) 
+int venus_statfs(struct super_block *sb, struct kstatfs *sfs) 
 { 
         union inputArgs *inp;
         union outputArgs *outp;
diff -puN fs/compat.c~statfs64-3 fs/compat.c
--- 25/fs/compat.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/compat.c	2003-06-16 00:51:16.000000000 -0700
@@ -87,8 +87,15 @@ asmlinkage long compat_sys_newfstat(unsi
 	return error;
 }
 
-static int put_compat_statfs(struct compat_statfs *ubuf, struct statfs *kbuf)
+static int put_compat_statfs(struct compat_statfs *ubuf, struct kstatfs *kbuf)
 {
+	
+	if (sizeof ubuf->f_blocks == 4) {
+		if ((kbuf->f_blocks | kbuf->f_bfree |
+		     kbuf->f_bavail | kbuf->f_files | kbuf->f_ffree) &
+		    0xffffffff00000000ULL)
+			return -EOVERFLOW;
+	}
 	if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
 	    __put_user(kbuf->f_type, &ubuf->f_type) ||
 	    __put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
@@ -99,7 +106,8 @@ static int put_compat_statfs(struct comp
 	    __put_user(kbuf->f_ffree, &ubuf->f_ffree) ||
 	    __put_user(kbuf->f_namelen, &ubuf->f_namelen) ||
 	    __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
-	    __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]))
+	    __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
+	    __put_user(kbuf->f_frsize, &ubuf->f_frsize))
 		return -EFAULT;
 	return 0;
 }
@@ -115,7 +123,7 @@ asmlinkage long compat_sys_statfs(const 
 
 	error = user_path_walk(path, &nd);
 	if (!error) {
-		struct statfs tmp;
+		struct kstatfs tmp;
 		error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
 		if (!error && put_compat_statfs(buf, &tmp))
 			error = -EFAULT;
@@ -127,7 +135,7 @@ asmlinkage long compat_sys_statfs(const 
 asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs *buf)
 {
 	struct file * file;
-	struct statfs tmp;
+	struct kstatfs tmp;
 	int error;
 
 	error = -EBADF;
diff -puN fs/cramfs/inode.c~statfs64-3 fs/cramfs/inode.c
--- 25/fs/cramfs/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/cramfs/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -266,7 +266,7 @@ out:
 	return -EINVAL;
 }
 
-static int cramfs_statfs(struct super_block *sb, struct statfs *buf)
+static int cramfs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	buf->f_type = CRAMFS_MAGIC;
 	buf->f_bsize = PAGE_CACHE_SIZE;
diff -puN fs/efs/super.c~statfs64-3 fs/efs/super.c
--- 25/fs/efs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/efs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -278,7 +278,7 @@ out_no_fs:
 	return -EINVAL;
 }
 
-int efs_statfs(struct super_block *s, struct statfs *buf) {
+int efs_statfs(struct super_block *s, struct kstatfs *buf) {
 	struct efs_sb_info *sb = SUPER_INFO(s);
 
 	buf->f_type    = EFS_SUPER_MAGIC;	/* efs magic number */
diff -puN fs/ext2/super.c~statfs64-3 fs/ext2/super.c
--- 25/fs/ext2/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/ext2/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -34,7 +34,7 @@
 static void ext2_sync_super(struct super_block *sb,
 			    struct ext2_super_block *es);
 static int ext2_remount (struct super_block * sb, int * flags, char * data);
-static int ext2_statfs (struct super_block * sb, struct statfs * buf);
+static int ext2_statfs (struct super_block * sb, struct kstatfs * buf);
 
 static char error_buf[1024];
 
@@ -939,7 +939,7 @@ static int ext2_remount (struct super_bl
 	return 0;
 }
 
-static int ext2_statfs (struct super_block * sb, struct statfs * buf)
+static int ext2_statfs (struct super_block * sb, struct kstatfs * buf)
 {
 	struct ext2_sb_info *sbi = EXT2_SB(sb);
 	unsigned long overhead;
diff -puN fs/ext3/super.c~statfs64-3 fs/ext3/super.c
--- 25/fs/ext3/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/ext3/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -1927,7 +1927,7 @@ int ext3_remount (struct super_block * s
 	return 0;
 }
 
-int ext3_statfs (struct super_block * sb, struct statfs * buf)
+int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
 {
 	struct ext3_super_block *es = EXT3_SB(sb)->s_es;
 	unsigned long overhead;
diff -puN fs/fat/inode.c~statfs64-3 fs/fat/inode.c
--- 25/fs/fat/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/fat/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -1019,7 +1019,7 @@ out_fail:
 	return error;
 }
 
-int fat_statfs(struct super_block *sb,struct statfs *buf)
+int fat_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	int free,nr;
        
diff -puN fs/freevxfs/vxfs_super.c~statfs64-3 fs/freevxfs/vxfs_super.c
--- 25/fs/freevxfs/vxfs_super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/freevxfs/vxfs_super.c	2003-06-16 00:51:16.000000000 -0700
@@ -55,7 +55,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 
 static void		vxfs_put_super(struct super_block *);
-static int		vxfs_statfs(struct super_block *, struct statfs *);
+static int		vxfs_statfs(struct super_block *, struct kstatfs *);
 
 static struct super_operations vxfs_super_ops = {
 	.read_inode =		vxfs_read_inode,
@@ -105,7 +105,7 @@ vxfs_put_super(struct super_block *sbp)
  *   This is everything but complete...
  */
 static int
-vxfs_statfs(struct super_block *sbp, struct statfs *bufp)
+vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp)
 {
 	struct vxfs_sb_info		*infp = VXFS_SBI(sbp);
 
diff -puN fs/hfs/super.c~statfs64-3 fs/hfs/super.c
--- 25/fs/hfs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/hfs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -40,7 +40,7 @@ MODULE_LICENSE("GPL");
 
 static void hfs_read_inode(struct inode *);
 static void hfs_put_super(struct super_block *);
-static int hfs_statfs(struct super_block *, struct statfs *);
+static int hfs_statfs(struct super_block *, struct kstatfs *);
 static void hfs_write_super(struct super_block *);
 
 static kmem_cache_t * hfs_inode_cachep;
@@ -195,7 +195,7 @@ static void hfs_put_super(struct super_b
  *
  * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks.
  */
-static int hfs_statfs(struct super_block *sb, struct statfs *buf)
+static int hfs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;
 
diff -puN fs/hpfs/hpfs_fn.h~statfs64-3 fs/hpfs/hpfs_fn.h
--- 25/fs/hpfs/hpfs_fn.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/hpfs/hpfs_fn.h	2003-06-16 00:51:16.000000000 -0700
@@ -310,7 +310,7 @@ int hpfs_stop_cycles(struct super_block 
 int hpfs_remount_fs(struct super_block *, int *, char *);
 void hpfs_put_super(struct super_block *);
 unsigned hpfs_count_one_bitmap(struct super_block *, secno);
-int hpfs_statfs(struct super_block *, struct statfs *);
+int hpfs_statfs(struct super_block *, struct kstatfs *);
 
 extern struct address_space_operations hpfs_aops;
 
diff -puN fs/hpfs/super.c~statfs64-3 fs/hpfs/super.c
--- 25/fs/hpfs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/hpfs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -136,7 +136,7 @@ static unsigned count_bitmaps(struct sup
 	return count;
 }
 
-int hpfs_statfs(struct super_block *s, struct statfs *buf)
+int hpfs_statfs(struct super_block *s, struct kstatfs *buf)
 {
 	struct hpfs_sb_info *sbi = hpfs_sb(s);
 	lock_kernel();
diff -puN fs/intermezzo/intermezzo_fs.h~statfs64-3 fs/intermezzo/intermezzo_fs.h
--- 25/fs/intermezzo/intermezzo_fs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/intermezzo/intermezzo_fs.h	2003-06-16 00:51:16.000000000 -0700
@@ -530,7 +530,7 @@ int do_rename(struct presto_file_set *fs
               struct dentry *old_dentry, struct dentry *new_dir,
               struct dentry *new_dentry, struct lento_vfs_context *info);
 int presto_do_statfs (struct presto_file_set *fset,
-                      struct statfs * buf);
+                      struct kstatfs * buf);
 
 int lento_setattr(const char *name, struct iattr *iattr,
                   struct lento_vfs_context *info);
diff -puN fs/isofs/inode.c~statfs64-3 fs/isofs/inode.c
--- 25/fs/isofs/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/isofs/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -74,7 +74,7 @@ static void isofs_put_super(struct super
 }
 
 static void isofs_read_inode(struct inode *);
-static int isofs_statfs (struct super_block *, struct statfs *);
+static int isofs_statfs (struct super_block *, struct kstatfs *);
 
 static kmem_cache_t *isofs_inode_cachep;
 
@@ -884,7 +884,7 @@ out_freesbi:
 	return -EINVAL;
 }
 
-static int isofs_statfs (struct super_block *sb, struct statfs *buf)
+static int isofs_statfs (struct super_block *sb, struct kstatfs *buf)
 {
 	buf->f_type = ISOFS_SUPER_MAGIC;
 	buf->f_bsize = sb->s_blocksize;
diff -puN fs/jfs/super.c~statfs64-3 fs/jfs/super.c
--- 25/fs/jfs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/jfs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -117,7 +117,7 @@ static void jfs_destroy_inode(struct ino
 	kmem_cache_free(jfs_inode_cachep, ji);
 }
 
-static int jfs_statfs(struct super_block *sb, struct statfs *buf)
+static int jfs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
 	s64 maxinodes;
diff -puN fs/libfs.c~statfs64-3 fs/libfs.c
--- 25/fs/libfs.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/libfs.c	2003-06-16 00:51:16.000000000 -0700
@@ -16,7 +16,7 @@ int simple_getattr(struct vfsmount *mnt,
 	return 0;
 }
 
-int simple_statfs(struct super_block *sb, struct statfs *buf)
+int simple_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	buf->f_type = sb->s_magic;
 	buf->f_bsize = PAGE_CACHE_SIZE;
diff -puN fs/minix/inode.c~statfs64-3 fs/minix/inode.c
--- 25/fs/minix/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/minix/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -19,7 +19,7 @@
 
 static void minix_read_inode(struct inode * inode);
 static void minix_write_inode(struct inode * inode, int wait);
-static int minix_statfs(struct super_block *sb, struct statfs *buf);
+static int minix_statfs(struct super_block *sb, struct kstatfs *buf);
 static int minix_remount (struct super_block * sb, int * flags, char * data);
 
 static void minix_delete_inode(struct inode *inode)
@@ -294,7 +294,7 @@ out_bad_sb:
 	return -EINVAL;
 }
 
-static int minix_statfs(struct super_block *sb, struct statfs *buf)
+static int minix_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct minix_sb_info *sbi = minix_sb(sb);
 	buf->f_type = sb->s_magic;
diff -puN fs/ncpfs/inode.c~statfs64-3 fs/ncpfs/inode.c
--- 25/fs/ncpfs/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/ncpfs/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -39,7 +39,7 @@
 
 static void ncp_delete_inode(struct inode *);
 static void ncp_put_super(struct super_block *);
-static int  ncp_statfs(struct super_block *, struct statfs *);
+static int  ncp_statfs(struct super_block *, struct kstatfs *);
 
 static kmem_cache_t * ncp_inode_cachep;
 
@@ -717,7 +717,7 @@ static void ncp_put_super(struct super_b
 	kfree(server);
 }
 
-static int ncp_statfs(struct super_block *sb, struct statfs *buf)
+static int ncp_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct dentry* d;
 	struct inode* i;
diff -puN fs/nfsd/nfs3xdr.c~statfs64-3 fs/nfsd/nfs3xdr.c
--- 25/fs/nfsd/nfs3xdr.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/nfsd/nfs3xdr.c	2003-06-16 00:51:16.000000000 -0700
@@ -866,7 +866,7 @@ int
 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd3_fsstatres *resp)
 {
-	struct statfs	*s = &resp->stats;
+	struct kstatfs	*s = &resp->stats;
 	u64		bs = s->f_bsize;
 
 	*p++ = xdr_zero;	/* no post_op_attr */
diff -puN fs/nfsd/nfs4xdr.c~statfs64-3 fs/nfsd/nfs4xdr.c
--- 25/fs/nfsd/nfs4xdr.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/nfsd/nfs4xdr.c	2003-06-16 00:51:16.000000000 -0700
@@ -1080,7 +1080,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
 	struct name_ent *owner = NULL;
 	struct name_ent *group = NULL;
 	struct svc_fh tempfh;
-	struct statfs statfs;
+	struct kstatfs statfs;
 	int buflen = *countp << 2;
 	u32 *attrlenp;
 	u32 dummy;
diff -puN fs/nfsd/nfsxdr.c~statfs64-3 fs/nfsd/nfsxdr.c
--- 25/fs/nfsd/nfsxdr.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/nfsd/nfsxdr.c	2003-06-16 00:51:16.000000000 -0700
@@ -441,7 +441,7 @@ int
 nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd_statfsres *resp)
 {
-	struct statfs	*stat = &resp->stats;
+	struct kstatfs	*stat = &resp->stats;
 
 	*p++ = htonl(NFSSVC_MAXBLKSIZE);	/* max transfer size */
 	*p++ = htonl(stat->f_bsize);
diff -puN fs/nfsd/vfs.c~statfs64-3 fs/nfsd/vfs.c
--- 25/fs/nfsd/vfs.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/nfsd/vfs.c	2003-06-16 00:51:16.000000000 -0700
@@ -1489,7 +1489,7 @@ out:
  * N.B. After this call fhp needs an fh_put
  */
 int
-nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct statfs *stat)
+nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
 {
 	int err = fh_verify(rqstp, fhp, 0, MAY_NOP);
 	if (!err && vfs_statfs(fhp->fh_dentry->d_inode->i_sb,stat))
diff -puN fs/nfs/inode.c~statfs64-3 fs/nfs/inode.c
--- 25/fs/nfs/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/nfs/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -53,7 +53,7 @@ static void nfs_delete_inode(struct inod
 static void nfs_put_super(struct super_block *);
 static void nfs_clear_inode(struct inode *);
 static void nfs_umount_begin(struct super_block *);
-static int  nfs_statfs(struct super_block *, struct statfs *);
+static int  nfs_statfs(struct super_block *, struct kstatfs *);
 static int  nfs_show_options(struct seq_file *, struct vfsmount *);
 
 static struct super_operations nfs_sops = { 
@@ -474,7 +474,7 @@ out_fail:
 }
 
 static int
-nfs_statfs(struct super_block *sb, struct statfs *buf)
+nfs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct nfs_server *server = NFS_SB(sb);
 	unsigned char blockbits;
diff -puN fs/ntfs/super.c~statfs64-3 fs/ntfs/super.c
--- 25/fs/ntfs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/ntfs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -1251,7 +1251,7 @@ static unsigned long __get_nr_free_mft_r
  *
  * Return 0 on success or -errno on error.
  */
-static int ntfs_statfs(struct super_block *sb, struct statfs *sfs)
+static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
 {
 	ntfs_volume *vol = NTFS_SB(sb);
 	s64 size;
diff -puN fs/open.c~statfs64-3 fs/open.c
--- 25/fs/open.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/open.c	2003-06-16 00:51:16.000000000 -0700
@@ -23,23 +23,85 @@
 
 #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
 
-int vfs_statfs(struct super_block *sb, struct statfs *buf)
+int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	int retval = -ENODEV;
 
 	if (sb) {
 		retval = -ENOSYS;
 		if (sb->s_op->statfs) {
-			memset(buf, 0, sizeof(struct statfs));
+			memset(buf, 0, sizeof(*buf));
 			retval = security_sb_statfs(sb);
 			if (retval)
 				return retval;
 			retval = sb->s_op->statfs(sb, buf);
+			if (retval == 0 && buf->f_frsize == 0)
+				buf->f_frsize = buf->f_bsize;
 		}
 	}
 	return retval;
 }
 
+static int vfs_statfs_native(struct super_block *sb, struct statfs *buf)
+{
+	struct kstatfs st;
+	int retval;
+
+	retval = vfs_statfs(sb, &st);
+	if (retval)
+		return retval;
+
+	if (sizeof(*buf) == sizeof(st))
+		memcpy(buf, &st, sizeof(st));
+	else {
+		if (sizeof buf->f_blocks == 4) {
+			if ((st.f_blocks | st.f_bfree |
+			     st.f_bavail | st.f_files | st.f_ffree) &
+			    0xffffffff00000000ULL)
+				return -EOVERFLOW;
+		}
+
+		buf->f_type = st.f_type;
+		buf->f_bsize = st.f_bsize;
+		buf->f_blocks = st.f_blocks;
+		buf->f_bfree = st.f_bfree;
+		buf->f_bavail = st.f_bavail;
+		buf->f_files = st.f_files;
+		buf->f_ffree = st.f_ffree;
+		buf->f_fsid = st.f_fsid;
+		buf->f_namelen = st.f_namelen;
+		buf->f_frsize = st.f_frsize;
+		memset(buf->f_spare, 0, sizeof(buf->f_spare));
+	}
+	return 0;
+}
+
+static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf)
+{
+	struct kstatfs st;
+	int retval;
+
+	retval = vfs_statfs(sb, &st);
+	if (retval)
+		return retval;
+
+	if (sizeof(*buf) == sizeof(st))
+		memcpy(buf, &st, sizeof(st));
+	else {
+		buf->f_type = st.f_type;
+		buf->f_bsize = st.f_bsize;
+		buf->f_blocks = st.f_blocks;
+		buf->f_bfree = st.f_bfree;
+		buf->f_bavail = st.f_bavail;
+		buf->f_files = st.f_files;
+		buf->f_ffree = st.f_ffree;
+		buf->f_fsid = st.f_fsid;
+		buf->f_namelen = st.f_namelen;
+		buf->f_frsize = st.f_frsize;
+		memset(buf->f_spare, 0, sizeof(buf->f_spare));
+	}
+	return 0;
+}
 
 asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
 {
@@ -49,14 +111,34 @@ asmlinkage long sys_statfs(const char __
 	error = user_path_walk(path, &nd);
 	if (!error) {
 		struct statfs tmp;
-		error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
-		if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs)))
+		error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp);
+		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
 			error = -EFAULT;
 		path_release(&nd);
 	}
 	return error;
 }
 
+
+asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf)
+{
+	struct nameidata nd;
+	long error;
+
+	if (sz != sizeof(*buf))
+		return -EINVAL;
+	error = user_path_walk(path, &nd);
+	if (!error) {
+		struct statfs64 tmp;
+		error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp);
+		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+			error = -EFAULT;
+		path_release(&nd);
+	}
+	return error;
+}
+
+
 asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf)
 {
 	struct file * file;
@@ -67,8 +149,29 @@ asmlinkage long sys_fstatfs(unsigned int
 	file = fget(fd);
 	if (!file)
 		goto out;
-	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
-	if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs)))
+	error = vfs_statfs_native(file->f_dentry->d_inode->i_sb, &tmp);
+	if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+		error = -EFAULT;
+	fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user *buf)
+{
+	struct file * file;
+	struct statfs64 tmp;
+	int error;
+
+	if (sz != sizeof(*buf))
+		return -EINVAL;
+
+	error = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto out;
+	error = vfs_statfs64(file->f_dentry->d_inode->i_sb, &tmp);
+	if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
 		error = -EFAULT;
 	fput(file);
 out:
diff -puN fs/qnx4/inode.c~statfs64-3 fs/qnx4/inode.c
--- 25/fs/qnx4/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/qnx4/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -126,7 +126,7 @@ static struct inode *qnx4_alloc_inode(st
 static void qnx4_destroy_inode(struct inode *inode);
 static void qnx4_read_inode(struct inode *);
 static int qnx4_remount(struct super_block *sb, int *flags, char *data);
-static int qnx4_statfs(struct super_block *, struct statfs *);
+static int qnx4_statfs(struct super_block *, struct kstatfs *);
 
 static struct super_operations qnx4_sops =
 {
@@ -276,7 +276,7 @@ unsigned long qnx4_block_map( struct ino
 	return block;
 }
 
-static int qnx4_statfs(struct super_block *sb, struct statfs *buf)
+static int qnx4_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	lock_kernel();
 
diff -puN fs/reiserfs/super.c~statfs64-3 fs/reiserfs/super.c
--- 25/fs/reiserfs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/reiserfs/super.c	2003-06-16 00:51:20.000000000 -0700
@@ -62,7 +62,7 @@ int is_reiserfs_super (struct super_bloc
 }
 
 static int reiserfs_remount (struct super_block * s, int * flags, char * data);
-static int reiserfs_statfs (struct super_block * s, struct statfs * buf);
+static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);
 
 static void reiserfs_write_super (struct super_block * s)
 {
@@ -1414,7 +1414,7 @@ static int reiserfs_fill_super (struct s
 }
 
 
-static int reiserfs_statfs (struct super_block * s, struct statfs * buf)
+static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf)
 {
   struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
   
diff -puN fs/romfs/inode.c~statfs64-3 fs/romfs/inode.c
--- 25/fs/romfs/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/romfs/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -176,7 +176,7 @@ outnobh:
 /* That's simple too. */
 
 static int
-romfs_statfs(struct super_block *sb, struct statfs *buf)
+romfs_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	buf->f_type = ROMFS_MAGIC;
 	buf->f_bsize = ROMBSIZE;
diff -puN fs/smbfs/inode.c~statfs64-3 fs/smbfs/inode.c
--- 25/fs/smbfs/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/smbfs/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -47,7 +47,7 @@
 
 static void smb_delete_inode(struct inode *);
 static void smb_put_super(struct super_block *);
-static int  smb_statfs(struct super_block *, struct statfs *);
+static int  smb_statfs(struct super_block *, struct kstatfs *);
 static int  smb_show_options(struct seq_file *, struct vfsmount *);
 
 static kmem_cache_t *smb_inode_cachep;
@@ -610,7 +610,7 @@ out_no_server:
 }
 
 static int
-smb_statfs(struct super_block *sb, struct statfs *buf)
+smb_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	int result;
 	
diff -puN fs/smbfs/proc.c~statfs64-3 fs/smbfs/proc.c
--- 25/fs/smbfs/proc.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/smbfs/proc.c	2003-06-16 00:51:16.000000000 -0700
@@ -3160,7 +3160,7 @@ smb_proc_settime(struct dentry *dentry, 
 }
 
 int
-smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
+smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr)
 {
 	struct smb_sb_info *server = SMB_SB(sb);
 	int result;
diff -puN fs/smbfs/proto.h~statfs64-3 fs/smbfs/proto.h
--- 25/fs/smbfs/proto.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/smbfs/proto.h	2003-06-16 00:51:16.000000000 -0700
@@ -29,7 +29,7 @@ extern int smb_proc_getattr(struct dentr
 extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
 extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor);
 extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr);
-extern int smb_proc_dskattr(struct super_block *sb, struct statfs *attr);
+extern int smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr);
 extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len);
 extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
 extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
diff -puN fs/super.c~statfs64-3 fs/super.c
--- 25/fs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -409,7 +409,7 @@ asmlinkage long sys_ustat(dev_t dev, str
 {
         struct super_block *s;
         struct ustat tmp;
-        struct statfs sbuf;
+        struct kstatfs sbuf;
 	int err = -EINVAL;
 
         s = user_get_super(dev);
diff -puN fs/sysv/inode.c~statfs64-3 fs/sysv/inode.c
--- 25/fs/sysv/inode.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/sysv/inode.c	2003-06-16 00:51:16.000000000 -0700
@@ -75,7 +75,7 @@ static void sysv_put_super(struct super_
 	kfree(sbi);
 }
 
-static int sysv_statfs(struct super_block *sb, struct statfs *buf)
+static int sysv_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct sysv_sb_info *sbi = SYSV_SB(sb);
 
diff -puN fs/udf/super.c~statfs64-3 fs/udf/super.c
--- 25/fs/udf/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/udf/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -95,7 +95,7 @@ static void udf_load_partdesc(struct sup
 static void udf_open_lvid(struct super_block *);
 static void udf_close_lvid(struct super_block *);
 static unsigned int udf_count_free(struct super_block *);
-static int udf_statfs(struct super_block *, struct statfs *);
+static int udf_statfs(struct super_block *, struct kstatfs *);
 
 /* UDF filesystem type */
 static struct super_block *udf_get_sb(struct file_system_type *fs_type,
@@ -1720,7 +1720,7 @@ udf_put_super(struct super_block *sb)
  *	Written, tested, and released.
  */
 static int
-udf_statfs(struct super_block *sb, struct statfs *buf)
+udf_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	buf->f_type = UDF_SUPER_MAGIC;
 	buf->f_bsize = sb->s_blocksize;
diff -puN fs/ufs/super.c~statfs64-3 fs/ufs/super.c
--- 25/fs/ufs/super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/ufs/super.c	2003-06-16 00:51:16.000000000 -0700
@@ -973,7 +973,7 @@ int ufs_remount (struct super_block * sb
 	return 0;
 }
 
-int ufs_statfs (struct super_block * sb, struct statfs * buf)
+int ufs_statfs (struct super_block * sb, struct kstatfs * buf)
 {
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
@@ -988,8 +988,8 @@ int ufs_statfs (struct super_block * sb,
 	buf->f_blocks = uspi->s_dsize;
 	buf->f_bfree = ufs_blkstofrags(fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree)) +
 		fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);
-	buf->f_bavail = (buf->f_bfree > ((buf->f_blocks / 100) * uspi->s_minfree))
-		? (buf->f_bfree - ((buf->f_blocks / 100) * uspi->s_minfree)) : 0;
+	buf->f_bavail = (buf->f_bfree > (((long)buf->f_blocks / 100) * uspi->s_minfree))
+		? (buf->f_bfree - (((long)buf->f_blocks / 100) * uspi->s_minfree)) : 0;
 	buf->f_files = uspi->s_ncg * uspi->s_ipg;
 	buf->f_ffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);
 	buf->f_namelen = UFS_MAXNAMLEN;
diff -puN fs/xfs/linux/xfs_super.c~statfs64-3 fs/xfs/linux/xfs_super.c
--- 25/fs/xfs/linux/xfs_super.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/xfs/linux/xfs_super.c	2003-06-16 00:51:16.000000000 -0700
@@ -477,7 +477,7 @@ linvfs_write_super(
 STATIC int
 linvfs_statfs(
 	struct super_block	*sb,
-	struct statfs		*statp)
+	struct kstatfs		*statp)
 {
 	vfs_t			*vfsp = LINVFS_GET_VFS(sb);
 	int			error;
@@ -673,7 +673,7 @@ linvfs_fill_super(
 	vnode_t			*rootvp;
 	struct vfs		*vfsp = vfs_allocate();
 	struct xfs_mount_args	*args = args_allocate(sb);
-	struct statfs		statvfs;
+	struct kstatfs		statvfs;
 	int			error;
 
 	vfsp->vfs_super = sb;
diff -puN fs/xfs/linux/xfs_vfs.c~statfs64-3 fs/xfs/linux/xfs_vfs.c
--- 25/fs/xfs/linux/xfs_vfs.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/xfs/linux/xfs_vfs.c	2003-06-16 00:51:16.000000000 -0700
@@ -134,7 +134,7 @@ vfs_root(
 int
 vfs_statvfs(
 	struct bhv_desc		*bdp,
-	struct statfs		*sp,
+	struct kstatfs		*sp,
 	struct vnode		*vp)
 {
 	struct bhv_desc		*next = bdp;
diff -puN fs/xfs/linux/xfs_vfs.h~statfs64-3 fs/xfs/linux/xfs_vfs.h
--- 25/fs/xfs/linux/xfs_vfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/xfs/linux/xfs_vfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -37,7 +37,7 @@
 struct fid;
 struct cred;
 struct vnode;
-struct statfs;
+struct kstatfs;
 struct seq_file;
 struct super_block;
 struct xfs_mount_args;
@@ -100,7 +100,7 @@ typedef int	(*vfs_unmount_t)(bhv_desc_t 
 typedef int	(*vfs_mntupdate_t)(bhv_desc_t *, int *,
 				struct xfs_mount_args *);
 typedef int	(*vfs_root_t)(bhv_desc_t *, struct vnode **);
-typedef int	(*vfs_statvfs_t)(bhv_desc_t *, struct statfs *, struct vnode *);
+typedef int	(*vfs_statvfs_t)(bhv_desc_t *, struct kstatfs *, struct vnode *);
 typedef int	(*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
 typedef int	(*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *);
 typedef int	(*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
@@ -167,7 +167,7 @@ extern int vfs_showargs(bhv_desc_t *, st
 extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
 extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
 extern int vfs_root(bhv_desc_t *, struct vnode **);
-extern int vfs_statvfs(bhv_desc_t *, struct statfs *, struct vnode *);
+extern int vfs_statvfs(bhv_desc_t *, struct kstatfs *, struct vnode *);
 extern int vfs_sync(bhv_desc_t *, int, struct cred *);
 extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *);
 extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
diff -puN fs/xfs/xfs_vfsops.c~statfs64-3 fs/xfs/xfs_vfsops.c
--- 25/fs/xfs/xfs_vfsops.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/fs/xfs/xfs_vfsops.c	2003-06-16 00:51:16.000000000 -0700
@@ -752,7 +752,7 @@ xfs_root(
 STATIC int
 xfs_statvfs(
 	bhv_desc_t	*bdp,
-	struct statfs	*statp,
+	struct kstatfs	*statp,
 	vnode_t		*vp)
 {
 	__uint64_t	fakeinos;
@@ -782,7 +782,7 @@ xfs_statvfs(
 		if (!mp->m_inoadd)
 #endif
 			statp->f_files =
-			    MIN(statp->f_files, (long)mp->m_maxicount);
+			    min_t(sector_t, statp->f_files, mp->m_maxicount);
 	statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
 	XFS_SB_UNLOCK(mp, s);
 
diff -puN include/asm-alpha/statfs.h~statfs64-3 include/asm-alpha/statfs.h
--- 25/include/asm-alpha/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-alpha/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,25 +1,6 @@
 #ifndef _ALPHA_STATFS_H
 #define _ALPHA_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	int f_type;
-	int f_bsize;
-	int f_blocks;
-	int f_bfree;
-	int f_bavail;
-	int f_files;
-	int f_ffree;
-	__kernel_fsid_t f_fsid;
-	int f_namelen;
-	int f_spare[6];
-};
+#include <asm-generic/statfs.h>
 
 #endif
diff -puN include/asm-arm/statfs.h~statfs64-3 include/asm-arm/statfs.h
--- 25/include/asm-arm/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-arm/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,25 +1,6 @@
 #ifndef _ASMARM_STATFS_H
 #define _ASMARM_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	long f_type;
-	long f_bsize;
-	long f_blocks;
-	long f_bfree;
-	long f_bavail;
-	long f_files;
-	long f_ffree;
-	__kernel_fsid_t f_fsid;
-	long f_namelen;
-	long f_spare[6];
-};
+#include <asm-generic/statfs.h>
 
 #endif
diff -puN include/asm-cris/statfs.h~statfs64-3 include/asm-cris/statfs.h
--- 25/include/asm-cris/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-cris/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,25 +1,6 @@
 #ifndef _CRIS_STATFS_H
 #define _CRIS_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	long f_type;
-	long f_bsize;
-	long f_blocks;
-	long f_bfree;
-	long f_bavail;
-	long f_files;
-	long f_ffree;
-	__kernel_fsid_t f_fsid;
-	long f_namelen;
-	long f_spare[6];
-};
+#include <asm-generic/statfs.h>
 
 #endif
diff -puN /dev/null include/asm-generic/statfs.h
--- /dev/null	2002-08-30 16:31:37.000000000 -0700
+++ 25-akpm/include/asm-generic/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -0,0 +1,37 @@
+#ifndef _GENERIC_STATFS_H
+#define _GENERIC_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+# include <linux/types.h>
+typedef __kernel_fsid_t	fsid_t;
+#endif
+
+struct statfs {
+	__u32 f_type;
+	__u32 f_bsize;
+	__u32 f_blocks;
+	__u32 f_bfree;
+	__u32 f_bavail;
+	__u32 f_files;
+	__u32 f_ffree;
+	__kernel_fsid_t f_fsid;
+	__u32 f_namelen;
+	__u32 f_frsize;
+	__u32 f_spare[5];
+};
+
+struct statfs64 {
+	__u32 f_type;
+	__u32 f_bsize;
+	__u64 f_blocks;
+	__u64 f_bfree;
+	__u64 f_bavail;
+	__u64 f_files;
+	__u64 f_ffree;
+	__kernel_fsid_t f_fsid;
+	__u32 f_namelen;
+	__u32 f_frsize;
+	__u32 f_spare[5];
+};
+
+#endif
diff -puN include/asm-h8300/statfs.h~statfs64-3 include/asm-h8300/statfs.h
--- 25/include/asm-h8300/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-h8300/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,25 +1,6 @@
 #ifndef _H8300_STATFS_H
 #define _H8300_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	long f_type;
-	long f_bsize;
-	long f_blocks;
-	long f_bfree;
-	long f_bavail;
-	long f_files;
-	long f_ffree;
-	__kernel_fsid_t f_fsid;
-	long f_namelen;
-	long f_spare[6];
-};
+#include <asm-generic/statfs.h>
 
 #endif /* _H8300_STATFS_H */
diff -puN include/asm-i386/statfs.h~statfs64-3 include/asm-i386/statfs.h
--- 25/include/asm-i386/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-i386/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,25 +1,6 @@
 #ifndef _I386_STATFS_H
 #define _I386_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	long f_type;
-	long f_bsize;
-	long f_blocks;
-	long f_bfree;
-	long f_bavail;
-	long f_files;
-	long f_ffree;
-	__kernel_fsid_t f_fsid;
-	long f_namelen;
-	long f_spare[6];
-};
+#include <asm-generic/statfs.h>
 
 #endif
diff -puN include/asm-i386/unistd.h~statfs64-3 include/asm-i386/unistd.h
--- 25/include/asm-i386/unistd.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-i386/unistd.h	2003-06-16 00:51:16.000000000 -0700
@@ -273,8 +273,10 @@
 #define __NR_clock_gettime	(__NR_timer_create+6)
 #define __NR_clock_getres	(__NR_timer_create+7)
 #define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
 
-#define NR_syscalls 268
+#define NR_syscalls 270
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff -puN include/asm-ia64/compat.h~statfs64-3 include/asm-ia64/compat.h
--- 25/include/asm-ia64/compat.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-ia64/compat.h	2003-06-16 00:51:16.000000000 -0700
@@ -99,7 +99,8 @@ struct compat_statfs {
 	int		f_ffree;
 	compat_fsid_t	f_fsid;
 	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_spare[6];
+	int		f_frsize;
+	int		f_spare[5];
 };
 
 #define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
diff -puN include/asm-ia64/statfs.h~statfs64-3 include/asm-ia64/statfs.h
--- 25/include/asm-ia64/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-ia64/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -6,11 +6,9 @@
  * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
-# ifndef __KERNEL_STRICT_NAMES
-#  include <linux/types.h>
-   typedef __kernel_fsid_t	fsid_t;
-# endif
-
+/*
+ * This is ugly --- we're already 64-bit, so just duplicate the definitions
+ */
 struct statfs {
 	long f_type;
 	long f_bsize;
@@ -21,7 +19,24 @@ struct statfs {
 	long f_ffree;
 	__kernel_fsid_t f_fsid;
 	long f_namelen;
-	long f_spare[6];
+	long f_frsize;
+	long f_spare[5];
 };
 
+
+struct statfs64 {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_frsize;
+	long f_spare[5];
+};
+
+
 #endif /* _ASM_IA64_STATFS_H */
diff -puN include/asm-ia64/unistd.h~statfs64-3 include/asm-ia64/unistd.h
--- 25/include/asm-ia64/unistd.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-ia64/unistd.h	2003-06-16 00:51:16.000000000 -0700
@@ -246,6 +246,10 @@
 #define __NR_sys_clock_gettime		1254
 #define __NR_sys_clock_getres		1255
 #define __NR_sys_clock_nanosleep	1256
+#define __NR_fstatfs64			1257
+#define __NR_statfs64			1258
+
+
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
diff -puN include/asm-m68k/statfs.h~statfs64-3 include/asm-m68k/statfs.h
--- 25/include/asm-m68k/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-m68k/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,25 +1,6 @@
 #ifndef _M68K_STATFS_H
 #define _M68K_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	long f_type;
-	long f_bsize;
-	long f_blocks;
-	long f_bfree;
-	long f_bavail;
-	long f_files;
-	long f_ffree;
-	__kernel_fsid_t f_fsid;
-	long f_namelen;
-	long f_spare[6];
-};
+#include <asm-generic/statfs.h>
 
 #endif /* _M68K_STATFS_H */
diff -puN include/asm-parisc/compat.h~statfs64-3 include/asm-parisc/compat.h
--- 25/include/asm-parisc/compat.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-parisc/compat.h	2003-06-16 00:51:16.000000000 -0700
@@ -97,7 +97,8 @@ struct compat_statfs {
 	s32		f_ffree;
 	__kernel_fsid_t	f_fsid;
 	s32		f_namelen;
-	s32		f_spare[6];
+	s32		f_frsize;
+	s32		f_spare[5];
 };
 
 #define COMPAT_RLIM_INFINITY 0xffffffff
diff -puN include/asm-parisc/statfs.h~statfs64-3 include/asm-parisc/statfs.h
--- 25/include/asm-parisc/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-parisc/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -9,6 +9,10 @@ typedef __kernel_fsid_t	fsid_t;
 
 #endif
 
+/*
+ * It appears that PARISC could be 64 _or_ 32 bit.
+ * 64-bit fields must be explicitly 64-bit in statfs64.
+ */
 struct statfs {
 	long f_type;
 	long f_bsize;
@@ -19,7 +23,22 @@ struct statfs {
 	long f_ffree;
 	__kernel_fsid_t f_fsid;
 	long f_namelen;
-	long f_spare[6];
+	long f_frsize;
+	long f_spare[5];
+};
+
+struct statfs64 {
+	long f_type;
+	long f_bsize;
+	u64 f_blocks;
+	u64 f_bfree;
+	u64 f_bavail;
+	u64 f_files;
+	u64 f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_frsize;
+	long f_spare[5];
 };
 
 #endif
diff -puN include/asm-ppc64/compat.h~statfs64-3 include/asm-ppc64/compat.h
--- 25/include/asm-ppc64/compat.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-ppc64/compat.h	2003-06-16 00:51:16.000000000 -0700
@@ -91,7 +91,8 @@ struct compat_statfs {
 	int		f_ffree;
 	compat_fsid_t	f_fsid;
 	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_spare[6];
+	int		f_frsize;
+	int		f_spare[5];
 };
 
 #define COMPAT_RLIM_OLD_INFINITY	0x7fffffff
diff -puN include/asm-ppc64/statfs.h~statfs64-3 include/asm-ppc64/statfs.h
--- 25/include/asm-ppc64/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-ppc64/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -13,6 +13,9 @@
 typedef __kernel_fsid_t	fsid_t;
 #endif
 
+/*
+ * We're already 64-bit, so duplicate the definition
+ */
 struct statfs {
 	long f_type;
 	long f_bsize;
@@ -23,7 +26,22 @@ struct statfs {
 	long f_ffree;
 	__kernel_fsid_t f_fsid;
 	long f_namelen;
-	long f_spare[6];
+	long f_frsize;
+	long f_spare[5];
+};
+
+struct statfs64 {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_frsize;
+	long f_spare[5];
 };
 
 #endif  /* _PPC64_STATFS_H */
diff -puN include/asm-ppc/statfs.h~statfs64-3 include/asm-ppc/statfs.h
--- 25/include/asm-ppc/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-ppc/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,27 +1,7 @@
 #ifndef _PPC_STATFS_H
 #define _PPC_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	long f_type;
-	long f_bsize;
-	long f_blocks;
-	long f_bfree;
-	long f_bavail;
-	long f_files;
-	long f_ffree;
-	__kernel_fsid_t f_fsid;
-	long f_namelen;
-	long f_spare[6];
-};
-
+#include <asm-generic/statfs.h>
 #endif
 
 
diff -puN include/asm-sparc64/statfs.h~statfs64-3 include/asm-sparc64/statfs.h
--- 25/include/asm-sparc64/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-sparc64/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -20,7 +20,22 @@ struct statfs {
 	long f_ffree;
 	__kernel_fsid_t f_fsid;
 	long f_namelen;
-	long f_spare[6];
+	long f_frsize;
+	long f_spare[5];
+};
+
+struct statfs64 {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_frsize;
+	long f_spare[5];
 };
 
 #endif
diff -puN include/asm-sparc/statfs.h~statfs64-3 include/asm-sparc/statfs.h
--- 25/include/asm-sparc/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-sparc/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -2,25 +2,6 @@
 #ifndef _SPARC_STATFS_H
 #define _SPARC_STATFS_H
 
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t	fsid_t;
-
-#endif
-
-struct statfs {
-	long f_type;
-	long f_bsize;
-	long f_blocks;
-	long f_bfree;
-	long f_bavail;
-	long f_files;
-	long f_ffree;
-	__kernel_fsid_t f_fsid;
-	long f_namelen;  /* SunOS ignores this field. */
-	long f_spare[6];
-};
+#include <asm-generic/statfs.h>
 
 #endif
diff -puN include/asm-x86_64/compat.h~statfs64-3 include/asm-x86_64/compat.h
--- 25/include/asm-x86_64/compat.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-x86_64/compat.h	2003-06-16 00:51:16.000000000 -0700
@@ -101,7 +101,8 @@ struct compat_statfs {
 	int		f_ffree;
 	compat_fsid_t	f_fsid;
 	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_spare[6];
+	int		f_frsize;
+	int		f_spare[5];
 };
 
 #define COMPAT_RLIM_OLD_INFINITY	0x7fffffff
diff -puN include/asm-x86_64/statfs.h~statfs64-3 include/asm-x86_64/statfs.h
--- 25/include/asm-x86_64/statfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/asm-x86_64/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -9,6 +9,10 @@ typedef __kernel_fsid_t	fsid_t;
 
 #endif
 
+/*
+ * This is ugly -- we're already 64-bit clean, so just duplicate the 
+ * definitions.
+ */
 struct statfs {
 	long f_type;
 	long f_bsize;
@@ -19,7 +23,22 @@ struct statfs {
 	long f_ffree;
 	__kernel_fsid_t f_fsid;
 	long f_namelen;
-	long f_spare[6];
+	long f_frsize;
+	long f_spare[5];
+};
+
+struct statfs64 {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_frsize;
+	long f_spare[5];
 };
 
 #endif
diff -puN include/linux/coda_psdev.h~statfs64-3 include/linux/coda_psdev.h
--- 25/include/linux/coda_psdev.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/coda_psdev.h	2003-06-16 00:51:16.000000000 -0700
@@ -73,7 +73,7 @@ int venus_pioctl(struct super_block *sb,
 		 unsigned int cmd, struct PioctlData *data);
 int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb);
 int venus_fsync(struct super_block *sb, struct ViceFid *fid);
-int venus_statfs(struct super_block *sb, struct statfs *sfs);
+int venus_statfs(struct super_block *sb, struct kstatfs *sfs);
 
 
 /* messages between coda filesystem in kernel and Venus */
diff -puN include/linux/efs_fs.h~statfs64-3 include/linux/efs_fs.h
--- 25/include/linux/efs_fs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/efs_fs.h	2003-06-16 00:51:16.000000000 -0700
@@ -41,7 +41,7 @@ extern struct file_operations efs_dir_op
 extern struct address_space_operations efs_symlink_aops;
 
 extern int efs_fill_super(struct super_block *, void *, int);
-extern int efs_statfs(struct super_block *, struct statfs *);
+extern int efs_statfs(struct super_block *, struct kstatfs *);
 
 extern void efs_read_inode(struct inode *);
 extern efs_block_t efs_map_block(struct inode *, efs_block_t);
diff -puN include/linux/ext3_fs.h~statfs64-3 include/linux/ext3_fs.h
--- 25/include/linux/ext3_fs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/ext3_fs.h	2003-06-16 00:51:16.000000000 -0700
@@ -761,7 +761,7 @@ extern void ext3_write_super (struct sup
 extern void ext3_write_super_lockfs (struct super_block *);
 extern void ext3_unlockfs (struct super_block *);
 extern int ext3_remount (struct super_block *, int *, char *);
-extern int ext3_statfs (struct super_block *, struct statfs *);
+extern int ext3_statfs (struct super_block *, struct kstatfs *);
 
 #define ext3_std_error(sb, errno)				\
 do {								\
diff -puN include/linux/fs.h~statfs64-3 include/linux/fs.h
--- 25/include/linux/fs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/fs.h	2003-06-16 00:51:16.000000000 -0700
@@ -25,7 +25,7 @@ struct iovec;
 struct nameidata;
 struct pipe_inode_info;
 struct poll_table_struct;
-struct statfs;
+struct kstatfs;
 struct vm_area_struct;
 struct vfsmount;
 
@@ -781,7 +781,7 @@ struct super_operations {
 	int (*sync_fs)(struct super_block *sb, int wait);
 	void (*write_super_lockfs) (struct super_block *);
 	void (*unlockfs) (struct super_block *);
-	int (*statfs) (struct super_block *, struct statfs *);
+	int (*statfs) (struct super_block *, struct kstatfs *);
 	int (*remount_fs) (struct super_block *, int *, char *);
 	void (*clear_inode) (struct inode *);
 	void (*umount_begin) (struct super_block *);
@@ -960,7 +960,7 @@ extern struct vfsmount *kern_mount(struc
 extern int may_umount(struct vfsmount *);
 extern long do_mount(char *, char *, char *, unsigned long, void *);
 
-extern int vfs_statfs(struct super_block *, struct statfs *);
+extern int vfs_statfs(struct super_block *, struct kstatfs *);
 
 /* Return value for VFS lock functions - tells locks.c to lock conventionally
  * REALLY kosha for root NFS and nfs_lock
@@ -1278,7 +1278,7 @@ extern int dcache_dir_close(struct inode
 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
 extern int dcache_readdir(struct file *, void *, filldir_t);
 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
-extern int simple_statfs(struct super_block *, struct statfs *);
+extern int simple_statfs(struct super_block *, struct kstatfs *);
 extern int simple_link(struct dentry *, struct inode *, struct dentry *);
 extern int simple_unlink(struct inode *, struct dentry *);
 extern int simple_rmdir(struct inode *, struct dentry *);
diff -puN include/linux/msdos_fs.h~statfs64-3 include/linux/msdos_fs.h
--- 25/include/linux/msdos_fs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/msdos_fs.h	2003-06-16 00:51:16.000000000 -0700
@@ -270,7 +270,7 @@ extern void fat_clear_inode(struct inode
 extern void fat_put_super(struct super_block *sb);
 int fat_fill_super(struct super_block *sb, void *data, int silent,
 		   struct inode_operations *fs_dir_inode_ops, int isvfat);
-extern int fat_statfs(struct super_block *sb, struct statfs *buf);
+extern int fat_statfs(struct super_block *sb, struct kstatfs *buf);
 extern void fat_write_inode(struct inode *inode, int wait);
 extern int fat_notify_change(struct dentry * dentry, struct iattr * attr);
 
diff -puN include/linux/nfsd/nfsd.h~statfs64-3 include/linux/nfsd/nfsd.h
--- 25/include/linux/nfsd/nfsd.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/nfsd/nfsd.h	2003-06-16 00:51:16.000000000 -0700
@@ -111,7 +111,7 @@ int		nfsd_truncate(struct svc_rqst *, st
 int		nfsd_readdir(struct svc_rqst *, struct svc_fh *,
 			     loff_t *, struct readdir_cd *, encode_dent_fn);
 int		nfsd_statfs(struct svc_rqst *, struct svc_fh *,
-				struct statfs *);
+				struct kstatfs *);
 
 int		nfsd_notify_change(struct inode *, struct iattr *);
 int		nfsd_permission(struct svc_export *, struct dentry *, int);
diff -puN include/linux/nfsd/xdr3.h~statfs64-3 include/linux/nfsd/xdr3.h
--- 25/include/linux/nfsd/xdr3.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/nfsd/xdr3.h	2003-06-16 00:51:16.000000000 -0700
@@ -176,7 +176,7 @@ struct nfsd3_readdirres {
 
 struct nfsd3_fsstatres {
 	__u32			status;
-	struct statfs		stats;
+	struct kstatfs		stats;
 	__u32			invarsec;
 };
 
diff -puN include/linux/nfsd/xdr.h~statfs64-3 include/linux/nfsd/xdr.h
--- 25/include/linux/nfsd/xdr.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/nfsd/xdr.h	2003-06-16 00:51:16.000000000 -0700
@@ -113,7 +113,7 @@ struct nfsd_readdirres {
 };
 
 struct nfsd_statfsres {
-	struct statfs		stats;
+	struct kstatfs		stats;
 };
 
 /*
diff -puN /dev/null include/linux/statfs.h
--- /dev/null	2002-08-30 16:31:37.000000000 -0700
+++ 25-akpm/include/linux/statfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -0,0 +1,22 @@
+#ifndef _LINUX_STATFS_H
+#define _LINUX_STATFS_H
+
+#include <linux/types.h>
+
+#include <asm/statfs.h>
+
+struct kstatfs {
+	long f_type;
+	long f_bsize;
+	sector_t f_blocks;
+	sector_t f_bfree;
+	sector_t f_bavail;
+	sector_t f_files;
+	sector_t f_ffree;
+	__kernel_fsid_t f_fsid;
+	long f_namelen;
+	long f_frsize;
+	long f_spare[5];
+};
+
+#endif
diff -puN include/linux/vfs.h~statfs64-3 include/linux/vfs.h
--- 25/include/linux/vfs.h~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/include/linux/vfs.h	2003-06-16 00:51:16.000000000 -0700
@@ -1,6 +1,6 @@
 #ifndef _LINUX_VFS_H
 #define _LINUX_VFS_H
 
-#include <asm/statfs.h>
+#include <linux/statfs.h>
 
 #endif
diff -puN kernel/acct.c~statfs64-3 kernel/acct.c
--- 25/kernel/acct.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/kernel/acct.c	2003-06-16 00:51:16.000000000 -0700
@@ -54,6 +54,7 @@
 #include <linux/jiffies.h>
 #include <asm/uaccess.h>
 #include <asm/div64.h>
+#include <linux/blkdev.h> /* sector_div */
 
 /*
  * These constants control the amount of freespace that suspend and
@@ -100,9 +101,11 @@ static void acct_timeout(unsigned long u
  */
 static int check_free_space(struct file *file)
 {
-	struct statfs sbuf;
+	struct kstatfs sbuf;
 	int res;
 	int act;
+	sector_t resume;
+	sector_t suspend;
 
 	spin_lock(&acct_globals.lock);
 	res = acct_globals.active;
@@ -113,10 +116,15 @@ static int check_free_space(struct file 
 	/* May block */
 	if (vfs_statfs(file->f_dentry->d_inode->i_sb, &sbuf))
 		return res;
+	suspend = sbuf.f_blocks * SUSPEND;
+	resume = sbuf.f_blocks * RESUME;
 
-	if (sbuf.f_bavail <= SUSPEND * sbuf.f_blocks / 100)
+	sector_div(suspend, 100);
+	sector_div(resume, 100);
+
+	if (sbuf.f_bavail <= suspend)
 		act = -1;
-	else if (sbuf.f_bavail >= RESUME * sbuf.f_blocks / 100)
+	else if (sbuf.f_bavail >= resume)
 		act = 1;
 	else
 		act = 0;
diff -puN mm/shmem.c~statfs64-3 mm/shmem.c
--- 25/mm/shmem.c~statfs64-3	2003-06-16 00:51:16.000000000 -0700
+++ 25-akpm/mm/shmem.c	2003-06-16 00:51:16.000000000 -0700
@@ -1352,7 +1352,7 @@ static ssize_t shmem_file_sendfile(struc
 	return desc.error;
 }
 
-static int shmem_statfs(struct super_block *sb, struct statfs *buf)
+static int shmem_statfs(struct super_block *sb, struct kstatfs *buf)
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
 

_