	This is based on released 2.3.27-pre1

	This is forward-adaptation of 2.3.26 baseline patch
	*without* compilation (nor running) tests!

		/Matti Aarnio <matti.aarnio@sonera.fi>


	This lacks support for arch/sh/ !

	Syscall vectors are *not* defined at this patch set!


		OVERVIEW:

        - FCNTL locks use 64-bit offsets natively, and the old interface
          is just a compability layer.
        
        - O_LARGEFILE defines for all archs
        
        - statvfs64 machinery in place of former statfs at the filesystems
          Also, moved related  copy_to_user()  from FS code to syscall
          interface -- allows cleaner wrapping/translation, etc.
  
        - pathconf machinery for all (important) filesystems; reports
          how several filesystem specific parameters are usable
        
        - mmap64() where file offset is 64-bit value (at 32-bit systems)
        
        - Offsets reported at  /proc/nnn/maps  are 32+PAGE_SIZE_BITS long
        
        - A few (compiler dependent) "can't compile 64-bit by constant"
          fixes -- some maskings and shifts..
        
        - EXT2 filesystem *is* ok to open file over 2G size (4G is not
          correct limit!) without O_LARGEFILE at 32-bit systems, but
          access beyond the boundary is not ok..  (read()/write()/lseek())
          ( But does allow any offset at  pwrite()/pread() )
        
        - resource limits are equiped with specifically 64-bit one
          for filesizes for all platforms -- so that no magic shifted 
          comparisons are needed..
  
        - Noticed (but didn't correct) several filesystems which still
          use old-tyle  update_vm_cache()  et.al. code.
          (As well as have XXX_bmap() )

        - Noticed that NFS would now really use NFSv3 patches as core
          infrastructure has reasonable support..
          (Changed several size/offset fields to __u64, but that isn't
           quite enough on overall..)
          
        - SingleUnixSpec: A seek done at a socket/pipe/fifo yields  ESPIPE

        - LFS: A seek which fails (goes beyond limits) must return pointer
               to original position before attempted seek.
               (Actually it speaks of presentable offsets..  and those
                only for REGULAR files, e.g. not device nodes!)   
          
        - getdents64() is extended somewhat to enable it to yield also
          other data during directory reading, than just inode number.
          (initially controlling flags must be '0', and no data is ever
           returned, but API extention is allowed without a new syscall!)
        
        - *stat64() family syscalls has extra 'flags' parameter which
          initially must be zero, but can be used to extend the syscall.
          
        - A bit of comment adding at 'struct file' definition about the
          read-ahead bits
          
        - Internal interfaces with new 64-bit size/position parameters:   
                do_truncate()
                vmtruncate()
                generic_buffer_fdatasync()
                do_mmap()
                truncate_inode_pages()
                nfs_proc_write(), nfs_proc_read()
                nfs_readreq_setup()
                smb_proc_write(), smb_proc_read()
          
        - kernel/acct.c: volume free space on/off switching limit
          changed to be able to work at least up to 0.95 * 4G blocks
          ( which hopefully is way more than 4 GB ) filesystems.
          
        - lib/vsprintf.c: Support  'L'  size definition (long long)
          for printing things without using  __divdi3/__moddi3 routines
          for the gcc builtins.


		TODO / NOTES

	- include/linux/fs.h
	VERIFY: block_write_cont_page()

	- include/linux/mm.h
	VERIFY: get_cached_page()

	VERIFY: all usage instanses of:  locks_verify_area()

	HFS has wrong thing at  hfs_bmap  (baseline bug)

	NTFS has wrong thing at  ntfs_bmap  (baseline bug)
	NTFS calls  update_vm_cache  (baseline bug)

	AFFS has wrong thing at  ntfs_bmap  (baseline bug)
	AFFS calls  update_vm_cache  (baseline bug)

	ADFS has wrong thing at  adfs_bmap  (baseline bug)

	NCPFS needs checking (page cache usage)

	QNX4 calls  update_vm_cache  (baseline bug)
	QNX4 has wrong thing as  qnx4_bmap  (baseline bug)

	SMBFS needs "page->index" verification ...  (baseline bug)

	UFS truncation ( truncate.c ) needs checking!

	KHTTPD needs updates ( sock_send_actor() code needs update )
	  (baseline bug)

	loopback driver could (?) be turned into LFS aware



diff -ur linux-23027p1/arch/alpha/kernel/osf_sys.c linux-23027p1m1/arch/alpha/kernel/osf_sys.c
--- linux-23027p1/arch/alpha/kernel/osf_sys.c	Thu Jul 29 23:37:22 1999
+++ linux-23027p1m1/arch/alpha/kernel/osf_sys.c	Mon Nov  8 22:58:50 1999
@@ -295,7 +295,7 @@
 	__kernel_fsid_t f_fsid;
 } *osf_stat;
 
-static int linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat, unsigned long bufsiz)
+static int linux_to_osf_statfs(struct statvfs64 *linux_stat, struct osf_statfs *osf_stat, unsigned long bufsiz)
 {
 	struct osf_statfs tmp_stat;
 
@@ -317,16 +317,15 @@
 
 static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsigned long bufsiz)
 {
-	struct statfs linux_stat;
+	struct statvfs64 linux_stat;
 	struct inode * inode = dentry->d_inode;
 	struct super_block * sb = inode->i_sb;
 	int error;
 
 	error = -ENODEV;
-	if (sb && sb->s_op && sb->s_op->statfs) {
-		set_fs(KERNEL_DS);
-		error = sb->s_op->statfs(sb, &linux_stat, sizeof(linux_stat));
-		set_fs(USER_DS);
+	if (sb && sb->s_op && sb->s_op->statvfs) {
+		memset(&linux_stat, 0, sizeof(linux_stat));
+		error = sb->s_op->statvfs(sb, &linux_stat);
 		if (!error)
 			error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);
 	}
diff -ur linux-23027p1/arch/arm/kernel/sys_arm.c linux-23027p1m1/arch/arm/kernel/sys_arm.c
--- linux-23027p1/arch/arm/kernel/sys_arm.c	Thu Oct 28 20:16:02 1999
+++ linux-23027p1m1/arch/arm/kernel/sys_arm.c	Mon Nov  8 22:58:50 1999
@@ -91,7 +91,43 @@
 	return error;
 }
 
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u32 fd;
+	__u64 offset; /* 64 bits */
+};
 
+asmlinkage long old_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	down(&current->mm->mmap_sem);
+	lock_kernel();
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+	if (file)
+		fput(file);
+out:
+	unlock_kernel();
+	up(&current->mm->mmap_sem);
+	return error;
+}
+ 
 extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 
 struct sel_arg_struct {
diff -ur linux-23027p1/arch/i386/kernel/sys_i386.c linux-23027p1m1/arch/i386/kernel/sys_i386.c
--- linux-23027p1/arch/i386/kernel/sys_i386.c	Wed Nov  3 21:31:09 1999
+++ linux-23027p1m1/arch/i386/kernel/sys_i386.c	Mon Nov  8 22:58:50 1999
@@ -85,6 +85,44 @@
 	return error;
 }
 
+
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u64 offset; /* 64 bits */
+	__u32 fd;
+};
+
+asmlinkage long old_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	down(&current->mm->mmap_sem);
+	lock_kernel();
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+	if (file)
+		fput(file);
+out:
+	unlock_kernel();
+	up(&current->mm->mmap_sem);
+	return error;
+}
+
 extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 
 struct sel_arg_struct {
diff -ur linux-23027p1/arch/m68k/kernel/sys_m68k.c linux-23027p1m1/arch/m68k/kernel/sys_m68k.c
--- linux-23027p1/arch/m68k/kernel/sys_m68k.c	Tue Jan 19 20:58:34 1999
+++ linux-23027p1m1/arch/m68k/kernel/sys_m68k.c	Mon Nov  8 22:58:50 1999
@@ -88,6 +88,42 @@
 	return error;
 }
 
+struct mmap_arg_struct64 {
+	__u32 addr;
+	__u32 len;
+	__u32 prot;
+	__u32 flags;
+	__u32 fd;
+	__u64 offset; /* 64 bits */
+};
+
+asmlinkage long old_mmap64(struct mmap_arg_struct64 *arg)
+{
+	int error = -EFAULT;
+	struct file * file = NULL;
+	struct mmap_arg_struct64 a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+
+	down(&current->mm->mmap_sem);
+	lock_kernel();
+	if (!(a.flags & MAP_ANONYMOUS)) {
+		error = -EBADF;
+		file = fget(a.fd);
+		if (!file)
+			goto out;
+	}
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+	if (file)
+		fput(file);
+out:
+	unlock_kernel();
+	up(&current->mm->mmap_sem);
+	return error;
+}
 
 extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 
diff -ur linux-23027p1/arch/mips/kernel/sysirix.c linux-23027p1m1/arch/mips/kernel/sysirix.c
--- linux-23027p1/arch/mips/kernel/sysirix.c	Sat Jun 26 03:40:12 1999
+++ linux-23027p1m1/arch/mips/kernel/sysirix.c	Mon Nov  8 22:58:50 1999
@@ -727,8 +727,7 @@
 {
 	struct dentry *dentry;
 	struct inode *inode;
-	mm_segment_t old_fs;
-	struct statfs kbuf;
+	struct statvfs64 kbuf;
 	int error, i;
 
 	lock_kernel();
@@ -747,10 +746,7 @@
 		goto out;
 
 	inode = dentry->d_inode;
-	old_fs = get_fs(); set_fs(get_ds());
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
-	                                  sizeof(struct statfs));
-	set_fs(old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &kbuf);
 	if (error)
 		goto dput_and_out;
 
@@ -777,8 +773,7 @@
 asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
 {
 	struct inode *inode;
-	struct statfs kbuf;
-	mm_segment_t old_fs;
+	struct statvfs64 kbuf;
 	struct file *file;
 	int error, i;
 
@@ -799,15 +794,12 @@
 		error = -ENODEV;
 		goto out_f;
 	}
-	if (!inode->i_sb->s_op->statfs) {
+	if (!inode->i_sb->s_op->statvfs) {
 		error = -ENOSYS;
 		goto out_f;
 	}
 
-	old_fs = get_fs(); set_fs(get_ds());
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
-	                                  sizeof(struct statfs));
-	set_fs(old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &kbuf);
 	if (error)
 		goto out_f;
 
@@ -1510,8 +1502,7 @@
 {
 	struct dentry *dentry;
 	struct inode *inode;
-	mm_segment_t old_fs;
-	struct statfs kbuf;
+	struct statvfs64 kbuf;
 	int error, i;
 
 	lock_kernel();
@@ -1527,13 +1518,10 @@
 	inode = dentry->d_inode;
 
 	error = -ENOSYS;
-	if(!inode->i_sb->s_op->statfs)
+	if(!inode->i_sb->s_op->statvfs)
 		goto dput_and_out;
 
-	old_fs = get_fs(); set_fs(get_ds());
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
-	                                  sizeof(struct statfs));
-	set_fs(old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &kbuf);
 	if (error)
 		goto dput_and_out;
 
@@ -1569,8 +1557,7 @@
 asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
 {
 	struct inode *inode;
-	mm_segment_t old_fs;
-	struct statfs kbuf;
+	struct statvfs64 kbuf;
 	struct file *file;
 	int error, i;
 
@@ -1593,15 +1580,12 @@
 		error = -ENODEV;
 		goto out_f;
 	}
-	if (!inode->i_sb->s_op->statfs) {
+	if (!inode->i_sb->s_op->statvfs) {
 		error = -ENOSYS;
 		goto out_f;
 	}
 
-	old_fs = get_fs(); set_fs(get_ds());
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
-	                                  sizeof(struct statfs));
-	set_fs(old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &kbuf);
 	if (error)
 		goto out_f;
 
@@ -1805,8 +1789,7 @@
 {
 	struct dentry *dentry;
 	struct inode *inode;
-	mm_segment_t old_fs;
-	struct statfs kbuf;
+	struct statvfs64 kbuf;
 	int error, i;
 
 	lock_kernel();
@@ -1821,13 +1804,10 @@
 		goto out;
 	error = -ENOSYS;
 	inode = dentry->d_inode;
-	if(!inode->i_sb->s_op->statfs)
+	if(!inode->i_sb->s_op->statvfs)
 		goto dput_and_out;
 
-	old_fs = get_fs(); set_fs(get_ds());
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
-	                                  sizeof(struct statfs));
-	set_fs(old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &kbuf);
 	if (error)
 		goto dput_and_out;
 
@@ -1863,8 +1843,7 @@
 asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
 {
 	struct inode *inode;
-	mm_segment_t old_fs;
-	struct statfs kbuf;
+	struct statvfs64 kbuf;
 	struct file *file;
 	int error, i;
 
@@ -1887,15 +1866,12 @@
 		error = -ENODEV;
 		goto out_f;
 	}
-	if (!inode->i_sb->s_op->statfs) {
+	if (!inode->i_sb->s_op->statvfs) {
 		error = -ENOSYS;
 		goto out_f;
 	}
 
-	old_fs = get_fs(); set_fs(get_ds());
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf,
-	                                  sizeof(struct statfs));
-	set_fs(old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &kbuf);
 	if (error)
 		goto out_f;
 
diff -ur linux-23027p1/arch/sparc64/solaris/fs.c linux-23027p1m1/arch/sparc64/solaris/fs.c
--- linux-23027p1/arch/sparc64/solaris/fs.c	Sat May 15 21:12:09 1999
+++ linux-23027p1m1/arch/sparc64/solaris/fs.c	Mon Nov  8 22:58:50 1999
@@ -299,30 +299,41 @@
 
 asmlinkage int solaris_statfs(u32 path, u32 buf, int len, int fstype)
 {
-	int ret;
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
-	int (*sys_statfs)(const char *,struct statfs *) = 
-		(int (*)(const char *,struct statfs *))SYS(statfs);
+	struct statvfs64 s;
 	struct sol_statfs *ss = (struct sol_statfs *)A(buf);
+	struct dentry *dentry;
+	struct inode *inode;
+	int error, i;
 	
 	if (len != sizeof(struct sol_statfs)) return -EINVAL;
+
+	lock_kernel();
+
 	if (!fstype) {
-		set_fs (KERNEL_DS);
-		ret = sys_statfs((const char *)A(path), &s);
-		set_fs (old_fs);
-		if (!ret) {
-			if (put_user (s.f_type, &ss->f_type)		||
-			    __put_user (s.f_bsize, &ss->f_bsize)	||
-			    __put_user (0, &ss->f_frsize)		||
-			    __put_user (s.f_blocks, &ss->f_blocks)	||
-			    __put_user (s.f_bfree, &ss->f_bfree)	||
-			    __put_user (s.f_files, &ss->f_files)	||
-			    __put_user (s.f_ffree, &ss->f_ffree)	||
-			    __clear_user (&ss->f_fname, 12))
-				return -EFAULT;
+		dentry = namei(path);
+		error = PTR_ERR(dentry);
+		if (IS_ERR(dentry))
+			goto out;
+
+		inode = dentry->d_inode;
+		error = inode->i_sb->s_op->statvfs(inode->i_sb, &s);
+		if (error)
+			goto dput_and_out;
+
+		if (put_user (s.f_type, &ss->f_type)		||
+		    __put_user (s.f_bsize, &ss->f_bsize)	||
+		    __put_user (0, &ss->f_frsize)		||
+		    __put_user (s.f_blocks, &ss->f_blocks)	||
+		    __put_user (s.f_bfree, &ss->f_bfree)	||
+		    __put_user (s.f_files, &ss->f_files)	||
+		    __put_user (s.f_ffree, &ss->f_ffree)	||
+		    __clear_user (&ss->f_fname, 12)) {
+			error = -EFAULT;
 		}
-		return ret;
+	dput_and_out:
+		dput(dentry);
+
+		goto out;
 	}
 /* Linux can't stat unmounted filesystems so we
  * simply lie and claim 100MB of 1GB is free. Sorry.
@@ -335,39 +346,68 @@
 	    __put_user (60000, &ss->f_files)		||
 	    __put_user (50000, &ss->f_ffree)		||
 	    __clear_user (&ss->f_fname, 12))
-		return -EFAULT;
-	return 0;
+		error = -EFAULT;
+
+out:
+	unlock_kernel();
+	return error;
 }
 
 asmlinkage int solaris_fstatfs(u32 fd, u32 buf, int len, int fstype)
 {
-	int ret;
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
-	int (*sys_fstatfs)(unsigned,struct statfs *) = 
-		(int (*)(unsigned,struct statfs *))SYS(fstatfs);
+	struct statvfs64 s;
 	struct sol_statfs *ss = (struct sol_statfs *)A(buf);
+	struct inode *inode;
+	struct file *file;
+	int error, i;
 	
 	if (len != sizeof(struct sol_statfs)) return -EINVAL;
-	if (!fstype) {
-		set_fs (KERNEL_DS);
-		ret = sys_fstatfs(fd, &s);
-		set_fs (old_fs);
-		if (!ret) {
-			if (put_user (s.f_type, &ss->f_type)		||
-			    __put_user (s.f_bsize, &ss->f_bsize)	||
-			    __put_user (0, &ss->f_frsize)		||
-			    __put_user (s.f_blocks, &ss->f_blocks)	||
-			    __put_user (s.f_bfree, &ss->f_bfree)	||
-			    __put_user (s.f_files, &ss->f_files)	||
-			    __put_user (s.f_ffree, &ss->f_ffree)	||
-			    __clear_user (&ss->f_fname, 12))
-				return -EFAULT;
-		}
-		return ret;
+
+	if (fstype) {
+	  /* Otherwise fstatfs is the same as statfs */
+	  return solaris_statfs(0, buf, len, fstype);
 	}
-	/* Otherwise fstatfs is the same as statfs */
-	return solaris_statfs(0, buf, len, fstype);
+
+	lock_kernel();
+
+	if (!(file = fget(fd))) {
+		error = -EBADF;
+		goto out;
+	}
+
+	if (!(inode = file->f_dentry->d_inode)) {
+		error = -ENOENT;
+		goto out_f;
+	}
+	if (!inode->i_sb) {
+		error = -ENODEV;
+		goto out_f;
+	}
+	if (!inode->i_sb->s_op->statvfs) {
+		error = -ENOSYS;
+		goto out_f;
+	}
+
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &s);
+	if (error)
+		goto out_f;
+
+	if (!error) {
+		if (put_user (s.f_type, &ss->f_type)		||
+		    __put_user (s.f_bsize, &ss->f_bsize)	||
+		    __put_user (0, &ss->f_frsize)		||
+		    __put_user (s.f_blocks, &ss->f_blocks)	||
+		    __put_user (s.f_bfree, &ss->f_bfree)	||
+		    __put_user (s.f_files, &ss->f_files)	||
+		    __put_user (s.f_ffree, &ss->f_ffree)	||
+		    __clear_user (&ss->f_fname, 12))
+			error = -EFAULT;
+	}
+out_f:
+	fput(file);
+out:
+	unlock_kernel();
+	return error;
 }
 
 struct sol_statvfs {
@@ -406,18 +446,15 @@
 
 static int report_statvfs(struct inode *inode, u32 buf)
 {
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
+	struct statvfs64 s;
 	int error;
 	struct sol_statvfs *ss = (struct sol_statvfs *)A(buf);
 
 	if (!inode->i_sb)
 		return -ENODEV;
-	if (!inode->i_sb->s_op->statfs)
+	if (!inode->i_sb->s_op->statvfs)
 		return -ENOSYS;
-	set_fs (KERNEL_DS);
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &s, sizeof(struct statfs));
-	set_fs (old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &s);
 	if (!error) {
 		const char *p = inode->i_sb->s_type->name;
 		int i = 0;
@@ -447,18 +484,15 @@
 
 static int report_statvfs64(struct inode *inode, u32 buf)
 {
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
+	struct statvfs64 s;
 	int error;
 	struct sol_statvfs64 *ss = (struct sol_statvfs64 *)A(buf);
 			
 	if (!inode->i_sb)
 		return -ENODEV;
-	if (!inode->i_sb->s_op->statfs)
+	if (!inode->i_sb->s_op->statvfs)
 		return -ENOSYS;
-	set_fs (KERNEL_DS);
-	error = inode->i_sb->s_op->statfs(inode->i_sb, &s, sizeof(struct statfs));
-	set_fs (old_fs);
+	error = inode->i_sb->s_op->statvfs(inode->i_sb, &s);
 	if (!error) {
 		const char *p = inode->i_sb->s_type->name;
 		int i = 0;
diff -ur linux-23027p1/fs/adfs/dir.c linux-23027p1m1/fs/adfs/dir.c
--- linux-23027p1/fs/adfs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/adfs/dir.c	Mon Nov  8 22:58:50 1999
@@ -9,6 +9,7 @@
 #include <linux/adfs_fs.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
+#include <linux/unistd.h>
 
 static ssize_t adfs_dirread (struct file *filp, char *buf,
 			     size_t siz, loff_t *ppos)
@@ -17,6 +18,7 @@
 }
 
 static int adfs_readdir (struct file *, void *, filldir_t);
+extern long adfs_pathconf(struct inode *, long);
 
 static struct file_operations adfs_dir_operations = {
 	NULL,			/* lseek - default */
@@ -32,7 +34,7 @@
 	file_fsync,		/* fsync */
 	NULL,			/* fasync */
 	NULL,			/* check_media_change */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
 };
 
 /*
@@ -346,4 +348,30 @@
 	}
 	adfs_dir_free (bh, buffers);
 	return 0;
+}
+
+long adfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return ADFS_NAME_LEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 2;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/adfs/file.c linux-23027p1m1/fs/adfs/file.c
--- linux-23027p1/fs/adfs/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/adfs/file.c	Mon Nov  8 22:58:50 1999
@@ -48,6 +48,8 @@
 	NULL			/* revalidate		*/
 };
 
+extern long adfs_pathconf(struct inode *, long);
+
 struct inode_operations adfs_file_inode_operations = {
 	&adfs_file_operations,	/* default file operations	*/
 	NULL,			/* create			*/
@@ -68,5 +70,6 @@
 	NULL,			/* truncate			*/
 	NULL,			/* permission			*/
 	NULL,			/* smap				*/
-	NULL			/* revalidate			*/
+	NULL,			/* revalidate			*/
+	adfs_pathconf,		/* pathconf			*/
 };
diff -ur linux-23027p1/fs/adfs/super.c linux-23027p1m1/fs/adfs/super.c
--- linux-23027p1/fs/adfs/super.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/adfs/super.c	Mon Nov  8 22:58:50 1999
@@ -23,7 +23,7 @@
 
 static void adfs_put_super(struct super_block *sb);
 static int adfs_remount(struct super_block *sb, int *flags, char *data);
-static int adfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int adfs_statvfs(struct super_block *sb, struct statvfs64 *buf);
 void adfs_read_inode(struct inode *inode);
 
 void adfs_error(struct super_block *sb, const char *function, const char *fmt, ...)
@@ -92,7 +92,7 @@
 	NULL,
 	adfs_put_super,
 	NULL,
-	adfs_statfs,
+	adfs_statvfs,
 	adfs_remount
 };
 
@@ -322,16 +322,15 @@
 	return NULL;
 }
 
-static int adfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int adfs_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
 	const unsigned int nidlen = sb->u.adfs_sb.s_idlen + 1;
 
-	tmp.f_type = ADFS_SUPER_MAGIC;
-	tmp.f_bsize = sb->s_blocksize;
-	tmp.f_blocks = sb->u.adfs_sb.s_dr->disc_size_high << (32 - sb->s_blocksize_bits) |
+	buf->f_type = ADFS_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = sb->u.adfs_sb.s_dr->disc_size_high << (32 - sb->s_blocksize_bits) |
 		       sb->u.adfs_sb.s_dr->disc_size >> sb->s_blocksize_bits;
-	tmp.f_files = tmp.f_blocks >> nidlen;
+	buf->f_files = buf->f_blocks >> nidlen;
 	{
 		unsigned int i, j = 0;
 		const unsigned mask = (1 << (nidlen - 1)) - 1;
@@ -373,12 +372,12 @@
 			else if (freelink)
 				adfs_error(sb, NULL, "undersized free fragment\n");
 		}
-		tmp.f_bfree = tmp.f_bavail = j <<
+		buf->f_bfree = buf->f_bavail = j <<
 			(sb->u.adfs_sb.s_dr->log2bpmb - sb->s_blocksize_bits);
 	}
-	tmp.f_ffree = tmp.f_bfree >> nidlen;
-	tmp.f_namelen = ADFS_NAME_LEN;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_ffree = buf->f_bfree >> nidlen;
+	buf->f_namelen = ADFS_NAME_LEN;
+	return 0;
 }
 
 static struct file_system_type adfs_fs_type = {
diff -ur linux-23027p1/fs/affs/dir.c linux-23027p1m1/fs/affs/dir.c
--- linux-23027p1/fs/affs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/affs/dir.c	Mon Nov  8 22:58:51 1999
@@ -23,9 +23,11 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/amigaffs.h>
+#include <linux/unistd.h>
 
 static int affs_readdir(struct file *, void *, filldir_t);
 static ssize_t affs_dir_read(struct file *, char *, size_t, loff_t *);
+extern long affs_pathconf(struct inode *inode, long option);
 
 static struct file_operations affs_dir_operations = {
 	NULL,			/* lseek - default */
@@ -64,7 +66,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permissions */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	affs_pathconf,		/* pathconf */
 };
 
 static ssize_t
@@ -181,4 +184,30 @@
 	affs_brelse(fh_bh);
 	pr_debug("AFFS: readdir()=%d\n",stored);
 	return stored;
+}
+
+long affs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return 30;	/* name component max length */
+	case _PC_NO_TRUNC:
+		return 0;	/* Will *silently* truncate */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return -INT_MAX; /* Unknown ?? */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/affs/file.c linux-23027p1m1/fs/affs/file.c
--- linux-23027p1/fs/affs/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/affs/file.c	Mon Nov  8 22:58:51 1999
@@ -560,7 +560,7 @@
 		sector = affs_bmap(inode,(u32)*ppos / blocksize);
 		if (!sector)
 			break;
-		offset = (u32)*ppos % blocksize;
+		offset = (u32)(*ppos) % blocksize;
 		bh = affs_bread(inode->i_dev,sector,AFFS_I2BSIZE(inode));
 		if (!bh)
 			break;
@@ -580,17 +580,17 @@
 affs_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
 {
 	struct inode		*inode = filp->f_dentry->d_inode;
-	off_t			 pos;
+	loff_t			 pos;
 	ssize_t			 written;
 	ssize_t			 c;
-	ssize_t			 blocksize;
+	ssize_t			 blocksize, blockshift;
 	struct buffer_head	*bh;
 	char			*p;
 
 	if (!count)
 		return 0;
-	pr_debug("AFFS: file_write(ino=%lu,pos=%lu,count=%d)\n",inode->i_ino,
-		 (unsigned long)*ppos,count);
+	pr_debug("AFFS: file_write(ino=%lu,pos=%Lu,count=%d)\n",inode->i_ino,
+		*ppos,count);
 
 	if (!inode) {
 		affs_error(inode->i_sb,"file_write","Inode = NULL");
@@ -609,16 +609,22 @@
 	else
 		pos = *ppos;
 	written   = 0;
-	blocksize = AFFS_I2BSIZE(inode);
+	blocksize = AFFS_I2BSIZE(inode); /* power of two! */
+	blockshift = AFFS_I2BITS(inode);
+
+	if (pos >= 0x7fffffff) /* Max size: 2G-1 */
+		return -EFBIG;
+	if ((pos + count) > 0x7fffffff)
+		count = 0x7fffffff - pos;
 
 	while (written < count) {
-		bh = affs_getblock(inode,pos / blocksize);
+		bh = affs_getblock(inode, pos >> blockshift);
 		if (!bh) {
 			if (!written)
 				written = -ENOSPC;
 			break;
 		}
-		c = blocksize - (pos % blocksize);
+		c = blocksize - (pos & (blocksize -1));
 		if (c > count - written)
 			c = count - written;
 		if (c != blocksize && !buffer_uptodate(bh)) {
@@ -631,7 +637,7 @@
 				break;
 			}
 		}
-		p  = (pos % blocksize) + bh->b_data;
+		p  = (pos & (blocksize -1)) + bh->b_data;
 		c -= copy_from_user(p,buf,c);
 		if (!c) {
 			affs_brelse(bh);
@@ -660,14 +666,15 @@
 {
 	struct inode		*inode = filp->f_dentry->d_inode;
 	off_t			 pos;
+	loff_t			 lpos;
 	ssize_t			 written;
 	ssize_t			 c;
 	ssize_t			 blocksize;
 	struct buffer_head	*bh;
 	char			*p;
 
-	pr_debug("AFFS: file_write_ofs(ino=%lu,pos=%lu,count=%d)\n",inode->i_ino,
-		(unsigned long)*ppos,count);
+	pr_debug("AFFS: file_write_ofs(ino=%lu,pos=%Lu,count=%d)\n",inode->i_ino,
+		*ppos,count);
 
 	if (!count)
 		return 0;
@@ -684,21 +691,25 @@
 	if (!inode->u.affs_i.i_ec && alloc_ext_cache(inode))
 		return -ENOMEM;
 	if (filp->f_flags & O_APPEND)
-		pos = inode->i_size;
+		lpos = inode->i_size;
 	else
-		pos = *ppos;
+		lpos = *ppos;
+
+	if (lpos > 0x7fffffffLL)
+		return -EFBIG;
 
+	pos = lpos;
 	bh        = NULL;
 	blocksize = AFFS_I2BSIZE(inode) - 24;
 	written   = 0;
 	while (written < count) {
-		bh = affs_getblock(inode,pos / blocksize);
+		bh = affs_getblock(inode,(u32)pos / blocksize);
 		if (!bh) {
 			if (!written)
 				written = -ENOSPC;
 			break;
 		}
-		c = blocksize - (pos % blocksize);
+		c = blocksize - ((u32)pos & blocksize);
 		if (c > count - written)
 			c = count - written;
 		if (c != blocksize && !buffer_uptodate(bh)) {
@@ -711,7 +722,7 @@
 				break;
 			}
 		}
-		p  = (pos % blocksize) + bh->b_data + 24;
+		p  = (((u_long)pos) % blocksize) + bh->b_data + 24;
 		c -= copy_from_user(p,buf,c);
 		if (!c) {
 			affs_brelse(bh);
@@ -780,10 +791,13 @@
 	int	 rem;
 	int	 ext;
 
-	pr_debug("AFFS: truncate(inode=%ld,size=%lu)\n",inode->i_ino,inode->i_size);
+	pr_debug("AFFS: truncate(inode=%ld,size=%Lu)\n",inode->i_ino,inode->i_size);
+	if (inode->i_size > 0x7fffffffULL)
+	  /* XXX Fine! No way to indicate an error. */
+	  return /* -EFBIG */;
 
 	net_blocksize = blocksize - ((inode->i_sb->u.affs_sb.s_flags & SF_OFS) ? 24 : 0);
-	first = (inode->i_size + net_blocksize - 1) / net_blocksize;
+	first = (u_long)(inode->i_size + net_blocksize - 1) / net_blocksize;
 	if (inode->u.affs_i.i_lastblock < first - 1) {
 		/* There has to be at least one new block to be allocated */
 		if (!inode->u.affs_i.i_ec && alloc_ext_cache(inode)) {
@@ -795,7 +809,7 @@
 			affs_warning(inode->i_sb,"truncate","Cannot extend file");
 			inode->i_size = net_blocksize * (inode->u.affs_i.i_lastblock + 1);
 		} else if (inode->i_sb->u.affs_sb.s_flags & SF_OFS) {
-			rem = inode->i_size % net_blocksize;
+			rem = ((u_long)inode->i_size) % net_blocksize;
 			DATA_FRONT(bh)->data_size = cpu_to_be32(rem ? rem : net_blocksize);
 			affs_fix_checksum(blocksize,bh->b_data,5);
 			mark_buffer_dirty(bh,0);
@@ -862,7 +876,7 @@
 			affs_free_block(inode->i_sb,ekey);
 		ekey = key;
 	}
-	block = ((inode->i_size + net_blocksize - 1) / net_blocksize) - 1;
+	block = ((u_long)(inode->i_size + net_blocksize - 1) / net_blocksize) - 1;
 	inode->u.affs_i.i_lastblock = block;
 
 	/* If the file is not truncated to a block boundary,
@@ -870,7 +884,7 @@
 	 * so it cannot become accessible again.
 	 */
 
-	rem = inode->i_size % net_blocksize;
+	rem = ((u_long)inode->i_size) % net_blocksize;
 	if (rem) {
 		if ((inode->i_sb->u.affs_sb.s_flags & SF_OFS)) 
 			rem += 24;
diff -ur linux-23027p1/fs/affs/inode.c linux-23027p1m1/fs/affs/inode.c
--- linux-23027p1/fs/affs/inode.c	Mon Mar  8 01:25:23 1999
+++ linux-23027p1m1/fs/affs/inode.c	Mon Nov  8 22:58:51 1999
@@ -146,7 +146,7 @@
 				block = AFFS_I2BSIZE(inode) - 24;
 			else
 				block = AFFS_I2BSIZE(inode);
-			inode->u.affs_i.i_lastblock = ((inode->i_size + block - 1) / block) - 1;
+			inode->u.affs_i.i_lastblock = (((u_long)inode->i_size + block - 1) / block) - 1;
 			break;
 		case ST_SOFTLINK:
 			inode->i_mode |= S_IFLNK;
diff -ur linux-23027p1/fs/affs/super.c linux-23027p1m1/fs/affs/super.c
--- linux-23027p1/fs/affs/super.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/affs/super.c	Mon Nov  8 22:58:51 1999
@@ -35,7 +35,7 @@
 
 #define MIN(a,b) (((a)<(b))?(a):(b))
 
-static int affs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int affs_statvfs(struct super_block *sb, struct statvfs64 *buf);
 static int affs_remount (struct super_block *sb, int *flags, char *data);
 
 static void
@@ -105,7 +105,7 @@
 	affs_notify_change,
 	affs_put_super,
 	affs_write_super,
-	affs_statfs,
+	affs_statvfs,
 	affs_remount
 };
 
@@ -662,23 +662,22 @@
 }
 
 static int
-affs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+affs_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
 	int		 free;
-	struct statfs	 tmp;
 
-	pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",sb->u.affs_sb.s_partition_size,
+	pr_debug("AFFS: statvfs() partsize=%d, reserved=%d\n",sb->u.affs_sb.s_partition_size,
 	     sb->u.affs_sb.s_reserved);
 
 	free          = affs_count_free_blocks(sb);
-	tmp.f_type    = AFFS_SUPER_MAGIC;
-	tmp.f_bsize   = sb->s_blocksize;
-	tmp.f_blocks  = sb->u.affs_sb.s_partition_size - sb->u.affs_sb.s_reserved;
-	tmp.f_bfree   = free;
-	tmp.f_bavail  = free;
-	tmp.f_files   = 0;
-	tmp.f_ffree   = 0;
-	return copy_to_user(buf,&tmp,bufsiz) ? -EFAULT : 0;
+	buf->f_type    = AFFS_SUPER_MAGIC;
+	buf->f_bsize   = sb->s_blocksize;
+	buf->f_blocks  = sb->u.affs_sb.s_partition_size - sb->u.affs_sb.s_reserved;
+	buf->f_bfree   = free;
+	buf->f_bavail  = free;
+	buf->f_files   = 0;
+	buf->f_ffree   = 0;
+	return 0;
 }
 
 static struct file_system_type affs_fs_type = {
diff -ur linux-23027p1/fs/autofs/inode.c linux-23027p1m1/fs/autofs/inode.c
--- linux-23027p1/fs/autofs/inode.c	Tue Jun  8 20:47:58 1999
+++ linux-23027p1m1/fs/autofs/inode.c	Mon Nov  8 22:58:51 1999
@@ -55,7 +55,7 @@
 #endif
 }
 
-static int autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int autofs_statvfs(struct super_block *sb, struct statvfs64 *buf);
 static void autofs_read_inode(struct inode *inode);
 static void autofs_write_inode(struct inode *inode);
 
@@ -67,7 +67,7 @@
 	NULL,			/* notify_change */
 	autofs_put_super,
 	NULL,			/* write_super */
-	autofs_statfs,
+	autofs_statvfs,
 	NULL
 };
 
@@ -277,19 +277,17 @@
 	return NULL;
 }
 
-static int autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int autofs_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	tmp.f_type = AUTOFS_SUPER_MAGIC;
-	tmp.f_bsize = 1024;
-	tmp.f_blocks = 0;
-	tmp.f_bfree = 0;
-	tmp.f_bavail = 0;
-	tmp.f_files = 0;
-	tmp.f_ffree = 0;
-	tmp.f_namelen = NAME_MAX;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = AUTOFS_SUPER_MAGIC;
+	buf->f_bsize = 1024;
+	buf->f_blocks = 0;
+	buf->f_bfree = 0;
+	buf->f_bavail = 0;
+	buf->f_files = 0;
+	buf->f_ffree = 0;
+	buf->f_namelen = NAME_MAX;
+	return 0;
 }
 
 static void autofs_read_inode(struct inode *inode)
diff -ur linux-23027p1/fs/bad_inode.c linux-23027p1m1/fs/bad_inode.c
--- linux-23027p1/fs/bad_inode.c	Sat Jun 26 22:04:39 1999
+++ linux-23027p1m1/fs/bad_inode.c	Mon Nov  8 22:58:51 1999
@@ -67,7 +67,8 @@
 	EIO_ERROR,		/* truncate */
 	EIO_ERROR,		/* permission */
 	EIO_ERROR,		/* smap */
-	EIO_ERROR		/* revalidate */
+	EIO_ERROR,		/* revalidate */
+	EIO_ERROR,		/* pathconf */
 };
 
 
diff -ur linux-23027p1/fs/bfs/inode.c linux-23027p1m1/fs/bfs/inode.c
--- linux-23027p1/fs/bfs/inode.c	Fri Nov  5 20:30:13 1999
+++ linux-23027p1m1/fs/bfs/inode.c	Mon Nov  8 22:58:51 1999
@@ -200,19 +200,17 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static int bfs_statfs(struct super_block *s, struct statfs *buf, int bufsiz)
+static int bfs_statvfs(struct super_block *s, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	tmp.f_type = BFS_MAGIC;
-	tmp.f_bsize = s->s_blocksize;
-	tmp.f_blocks = s->su_blocks;
-	tmp.f_bfree = tmp.f_bavail = s->su_freeb;
-	tmp.f_files = s->su_lasti + 1 - BFS_ROOT_INO;
-	tmp.f_ffree = s->su_freei;
-	tmp.f_fsid.val[0] = s->s_dev;
-	tmp.f_namelen = BFS_NAMELEN;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = BFS_MAGIC;
+	buf->f_bsize = s->s_blocksize;
+	buf->f_blocks = s->su_blocks;
+	buf->f_bfree = buf->f_bavail = s->su_freeb;
+	buf->f_files = s->su_lasti + 1 - BFS_ROOT_INO;
+	buf->f_ffree = s->su_freei;
+	buf->f_fsid.val[0] = s->s_dev;
+	buf->f_namelen = BFS_NAMELEN;
+	return 0;
 }
 
 static void bfs_write_super(struct super_block *s)
@@ -230,7 +228,7 @@
 	notify_change:	NULL,
 	put_super:	bfs_put_super,
 	write_super:	bfs_write_super,
-	statfs:		bfs_statfs,
+	statvfs:	bfs_statvfs,
 	remount_fs:	NULL,
 	clear_inode:	NULL,
 	umount_begin:	NULL
diff -ur linux-23027p1/fs/buffer.c linux-23027p1m1/fs/buffer.c
--- linux-23027p1/fs/buffer.c	Fri Nov  5 05:36:33 1999
+++ linux-23027p1m1/fs/buffer.c	Mon Nov  8 22:58:51 1999
@@ -43,6 +43,7 @@
 #include <linux/quotaops.h>
 #include <linux/iobuf.h>
 #include <linux/highmem.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -ur linux-23027p1/fs/coda/dir.c linux-23027p1m1/fs/coda/dir.c
--- linux-23027p1/fs/coda/dir.c	Mon Aug 23 20:14:44 1999
+++ linux-23027p1m1/fs/coda/dir.c	Mon Nov  8 22:58:51 1999
@@ -18,6 +18,7 @@
 #include <asm/segment.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
+#include <linux/unistd.h>
 
 #include <linux/coda.h>
 #include <linux/coda_linux.h>
@@ -50,7 +51,8 @@
 /* support routines */
 static int coda_venus_readdir(struct file *filp, void *dirent, 
 			      filldir_t filldir);
-int coda_fsync(struct file *, struct dentry *dentry);
+extern int coda_fsync(struct file *, struct dentry *dentry);
+extern long coda_pathconf(struct inode *, long);
 
 int coda_crossvol_rename = 0;
 int coda_hasmknod = 0;
@@ -84,8 +86,8 @@
 	NULL,	                /* truncate */
 	coda_permission,        /* permission */
 	NULL,                   /* smap */
-	NULL,                   /* update page */
-        coda_revalidate_inode   /* revalidate */
+	coda_revalidate_inode,	/* revalidate */
+	coda_pathconf,		/* pathconf */
 };
 
 struct file_operations coda_dir_operations = {
@@ -909,3 +911,29 @@
 	return 0;
 }
 
+long coda_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return CODA_MAXNAMLEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+		return 1;	/* Will yield -ENAMETOOLONG */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32; /* 64-bits really, except local cache isn't
+			      very good (at all) at it... */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return -INT_MAX; /* Unknown ?? */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
diff -ur linux-23027p1/fs/coda/file.c linux-23027p1m1/fs/coda/file.c
--- linux-23027p1/fs/coda/file.c	Sat Oct 30 02:45:32 1999
+++ linux-23027p1m1/fs/coda/file.c	Mon Nov  8 22:58:51 1999
@@ -32,7 +32,8 @@
 static int coda_file_mmap(struct file * file, struct vm_area_struct * vma);
 
 /* also exported from this file (used for dirs) */
-int coda_fsync(struct file *, struct dentry *dentry);
+extern int coda_fsync(struct file *, struct dentry *dentry);
+extern long coda_pathconf(struct inode *, long);
 
 struct inode_operations coda_file_inode_operations = {
 	&coda_file_operations,	/* default file operations */
@@ -54,7 +55,8 @@
 	NULL,			/* truncate */
         coda_permission,        /* permission */
 	NULL,                   /* smap */
-        coda_revalidate_inode   /* revalidate */
+	coda_revalidate_inode,	/* revalidate */
+	coda_pathconf,		/* pathconf */
 };
 
 struct file_operations coda_file_operations = {
@@ -98,7 +100,7 @@
         coda_prepare_openfile(coda_inode, coda_file, cii->c_ovp,
 			      &cont_file, &cont_dentry);
 
-        CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", 
+        CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page index: %lx\n", 
 	       coda_inode->i_ino, cii->c_ovp->i_ino, page->index);
 
         block_read_full_page(&cont_file, page);
diff -ur linux-23027p1/fs/coda/inode.c linux-23027p1m1/fs/coda/inode.c
--- linux-23027p1/fs/coda/inode.c	Mon Aug 23 20:14:44 1999
+++ linux-23027p1m1/fs/coda/inode.c	Mon Nov  8 22:58:51 1999
@@ -38,8 +38,7 @@
 static void coda_put_inode(struct inode *);
 static void coda_delete_inode(struct inode *);
 static void coda_put_super(struct super_block *);
-static int coda_statfs(struct super_block *sb, struct statfs *buf, 
-		       int bufsiz);
+static int coda_statvfs(struct super_block *sb, struct statvfs64 *buf);
 
 /* exported operations */
 struct super_operations coda_super_operations =
@@ -51,7 +50,7 @@
 	coda_notify_change,	/* notify_change */
 	coda_put_super,	        /* put_super */
 	NULL,			/* write_super */
-	coda_statfs,   		/* statfs */
+	coda_statvfs,  		/* statvfs */
 	NULL			/* remount_fs */
 };
 
@@ -237,31 +236,25 @@
         return error;
 }
 
-static int coda_statfs(struct super_block *sb, struct statfs *buf, 
-		       int bufsiz)
+static int coda_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
 	int error;
 
-	memset(&tmp, 0, sizeof(struct statfs));
-
-	error = venus_statfs(sb, &tmp);
+	error = venus_statvfs(sb, buf);
 
 	if (error) {
 		/* fake something like AFS does */
-		tmp.f_blocks = 9000000;
-		tmp.f_bfree  = 9000000;
-		tmp.f_bavail = 9000000;
-		tmp.f_files  = 9000000;
-		tmp.f_ffree  = 9000000;
+		buf->f_blocks = 9000000;
+		buf->f_bfree  = 9000000;
+		buf->f_bavail = 9000000;
+		buf->f_files  = 9000000;
+		buf->f_ffree  = 9000000;
 	}
 
 	/* and fill in the rest */
-	tmp.f_type = CODA_SUPER_MAGIC;
-	tmp.f_bsize = 1024;
-	tmp.f_namelen = CODA_MAXNAMLEN;
-
-	copy_to_user(buf, &tmp, bufsiz);
+	buf->f_type = CODA_SUPER_MAGIC;
+	buf->f_bsize = 1024;
+	buf->f_namelen = CODA_MAXNAMLEN;
 
 	return 0; 
 }
diff -ur linux-23027p1/fs/coda/upcall.c linux-23027p1m1/fs/coda/upcall.c
--- linux-23027p1/fs/coda/upcall.c	Tue Aug 31 21:30:48 1999
+++ linux-23027p1m1/fs/coda/upcall.c	Mon Nov  8 22:58:51 1999
@@ -580,7 +580,7 @@
 	return error;
 }
 
-int venus_statfs(struct super_block *sb, struct statfs *sfs) 
+int venus_statvfs(struct super_block *sb, struct statvfs64 *sfs) 
 { 
         union inputArgs *inp;
         union outputArgs *outp;
diff -ur linux-23027p1/fs/devices.c linux-23027p1m1/fs/devices.c
--- linux-23027p1/fs/devices.c	Sun Jul  4 20:02:30 1999
+++ linux-23027p1m1/fs/devices.c	Mon Nov  8 22:58:51 1999
@@ -285,7 +285,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	NULL,			/* pathconf */
 };
 
 /*
@@ -342,7 +343,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	NULL,			/* pathconf */
 };
 
 /*
diff -ur linux-23027p1/fs/devpts/inode.c linux-23027p1m1/fs/devpts/inode.c
--- linux-23027p1/fs/devpts/inode.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/devpts/inode.c	Mon Nov  8 22:58:51 1999
@@ -57,7 +57,7 @@
 #endif
 }
 
-static int devpts_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int devpts_statvfs(struct super_block *sb, struct statvfs64 *buf);
 static void devpts_read_inode(struct inode *inode);
 static void devpts_write_inode(struct inode *inode);
 
@@ -69,7 +69,7 @@
 	NULL,			/* notify_change */
 	devpts_put_super,
 	NULL,			/* write_super */
-	devpts_statfs,
+	devpts_statvfs,
 	NULL,			/* remount_fs */
 	NULL,			/* clear_inode */
 };
@@ -244,19 +244,17 @@
 	return NULL;
 }
 
-static int devpts_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int devpts_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	tmp.f_type = DEVPTS_SUPER_MAGIC;
-	tmp.f_bsize = 1024;
-	tmp.f_blocks = 0;
-	tmp.f_bfree = 0;
-	tmp.f_bavail = 0;
-	tmp.f_files = 0;
-	tmp.f_ffree = 0;
-	tmp.f_namelen = NAME_MAX;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = DEVPTS_SUPER_MAGIC;
+	buf->f_bsize = 1024;
+	buf->f_blocks = 0;
+	buf->f_bfree = 0;
+	buf->f_bavail = 0;
+	buf->f_files = 0;
+	buf->f_ffree = 0;
+	buf->f_namelen = NAME_MAX;
+	return 0;
 }
 
 static void devpts_read_inode(struct inode *inode)
diff -ur linux-23027p1/fs/dquot.c linux-23027p1m1/fs/dquot.c
--- linux-23027p1/fs/dquot.c	Thu Oct  7 22:47:37 1999
+++ linux-23027p1m1/fs/dquot.c	Mon Nov  8 23:08:46 1999
@@ -513,6 +513,8 @@
 	dquot = find_best_candidate_weighted();
 	if (dquot)
 		goto got_it;
+
+	count = 2; // "count" not initialized above!
 	/*
 	 * Try pruning the dcache to free up some dquots ...
 	 */
@@ -1308,7 +1310,11 @@
 	if (!S_ISREG(inode->i_mode))
 		goto cleanup;
 	error = -EINVAL;
-	if (inode->i_size == 0 || (inode->i_size % sizeof(struct dqblk)) != 0)
+
+	if (inode->i_size == 0 ||
+	    // Following cast isn't necessary in case compiler is egcs-1.1.2,
+	    // but it is needed with gcc-2.7.2.*
+	    ((u_long)inode->i_size % sizeof(struct dqblk)) != 0)
 		goto cleanup;
 
 	/* OK, there we go */
diff -ur linux-23027p1/fs/efs/super.c linux-23027p1m1/fs/efs/super.c
--- linux-23027p1/fs/efs/super.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/efs/super.c	Mon Nov  8 22:58:51 1999
@@ -13,6 +13,8 @@
 #include <linux/efs_vh.h>
 #include <linux/efs_fs_sb.h>
 
+static int efs_statvfs(struct super_block *s, struct statvfs64 *buf);
+
 static struct file_system_type efs_fs_type = {
 	"efs",			/* filesystem name */
 	FS_REQUIRES_DEV,	/* fs_flags */
@@ -28,7 +30,7 @@
 	NULL,		/* notify_change */
 	efs_put_super,	/* put_super */
 	NULL,		/* write_super */
-	efs_statfs,	/* statfs */
+	efs_statvfs,	/* statvfs */
 	NULL		/* remount */
 };
 
@@ -231,24 +233,23 @@
 	MOD_DEC_USE_COUNT;
 }
 
-int efs_statfs(struct super_block *s, struct statfs *buf, int bufsiz) {
+int efs_statvfs(struct super_block *s, struct statvfs64 *buf) {
 	struct statfs ret;
 	struct efs_sb_info *sb = SUPER_INFO(s);
 
-	ret.f_type    = EFS_SUPER_MAGIC;	/* efs magic number */
-	ret.f_bsize   = EFS_BLOCKSIZE;		/* blocksize */
-	ret.f_blocks  = sb->total_groups *	/* total data blocks */
+	buf->f_type    = EFS_SUPER_MAGIC;	/* efs magic number */
+	buf->f_bsize   = EFS_BLOCKSIZE;		/* blocksize */
+	buf->f_blocks  = sb->total_groups *	/* total data blocks */
 			(sb->group_size - sb->inode_blocks);
-	ret.f_bfree   = sb->data_free;		/* free data blocks */
-	ret.f_bavail  = sb->data_free;		/* free blocks for non-root */
-	ret.f_files   = sb->total_groups *	/* total inodes */
+	buf->f_bfree   = sb->data_free;		/* free data blocks */
+	buf->f_bavail  = sb->data_free;		/* free blocks for non-root */
+	buf->f_files   = sb->total_groups *	/* total inodes */
 			sb->inode_blocks *
 			(EFS_BLOCKSIZE / sizeof(struct efs_dinode));
-	ret.f_ffree   = sb->inode_free;	/* free inodes */
-	ret.f_fsid.val[0] = (sb->fs_magic >> 16) & 0xffff; /* fs ID */
-	ret.f_fsid.val[1] =  sb->fs_magic        & 0xffff; /* fs ID */
-	ret.f_namelen = EFS_MAXNAMELEN;		/* max filename length */
+	buf->f_ffree   = sb->inode_free;	/* free inodes */
+	buf->f_fsid.val[0] = (sb->fs_magic >> 16) & 0xffff; /* fs ID */
+	buf->f_fsid.val[1] =  sb->fs_magic        & 0xffff; /* fs ID */
+	buf->f_namelen = EFS_MAXNAMELEN;		/* max filename length */
 
-	return copy_to_user(buf, &ret, bufsiz) ? -EFAULT : 0;
+	return 0;
 }
-
diff -ur linux-23027p1/fs/efs/symlink.c linux-23027p1m1/fs/efs/symlink.c
--- linux-23027p1/fs/efs/symlink.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/efs/symlink.c	Mon Nov  8 22:58:51 1999
@@ -42,7 +42,7 @@
 	efs_block_t size = in->i_size;
   
 	if (size > 2 * EFS_BLOCKSIZE) {
-		printk(KERN_ERR "EFS: linktarget(): name too long: %lu\n", in->i_size);
+		printk(KERN_ERR "EFS: linktarget(): name too long: %Lu\n", in->i_size);
 		return NULL;
 	}
   
diff -ur linux-23027p1/fs/ext2/dir.c linux-23027p1m1/fs/ext2/dir.c
--- linux-23027p1/fs/ext2/dir.c	Thu Oct 28 23:23:10 1999
+++ linux-23027p1m1/fs/ext2/dir.c	Mon Nov  8 22:58:51 1999
@@ -30,6 +30,7 @@
 }
 
 static int ext2_readdir(struct file *, void *, filldir_t);
+extern long ext2_pathconf(struct inode *, long);
 
 static struct file_operations ext2_dir_operations = {
 	NULL,			/* lseek - default */
@@ -71,7 +72,8 @@
 	NULL,			/* truncate */
 	ext2_permission,	/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ext2_pathconf,		/* pathconf */
 };
 
 int ext2_check_dir_entry (const char * function, struct inode * dir,
diff -ur linux-23027p1/fs/ext2/file.c linux-23027p1m1/fs/ext2/file.c
--- linux-23027p1/fs/ext2/file.c	Fri Nov  5 19:57:30 1999
+++ linux-23027p1m1/fs/ext2/file.c	Mon Nov  8 22:58:51 1999
@@ -21,8 +21,9 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/unistd.h>
 
-
+extern long ext2_pathconf(struct inode *, long);
 
 #define	NBUF	32
 
@@ -30,9 +31,6 @@
 #define MAX(a,b) (((a)>(b))?(a):(b))
 
 static long long ext2_file_lseek(struct file *, long long, int);
-#if BITS_PER_LONG < 64
-static int ext2_open_file (struct inode *, struct file *);
-#endif
 
 #define EXT2_MAX_SIZE(bits)							\
 	(((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) + 				\
@@ -45,9 +43,6 @@
 EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
 };
 
-/*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
 static long long ext2_file_lseek(
 	struct file *file,
 	long long offset,
@@ -62,10 +57,19 @@
 		case 1:
 			offset += file->f_pos;
 	}
-	if (((unsigned long long) offset >> 32) != 0) {
+	if (offset < 0)
+		return -EINVAL;
+	if ((offset >> 32) != 0) {
 		if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
 			return -EINVAL;
 	} 
+
+	/* L-F-S spec 2.2.1.27: */
+	if (!(file->f_flags & O_LARGEFILE)) {
+		if (!off_t_presentable(offset +1)) /* pos@LONG_MAX forbidden */
+			return -EOVERFLOW;
+	}
+
 	if (offset != file->f_pos) {
 		file->f_pos = offset;
 		file->f_reada = 0;
@@ -120,20 +124,6 @@
 	return 0;
 }
 
-#if BITS_PER_LONG < 64
-/*
- * Called when an inode is about to be open.
- * We use this to disallow opening RW large files on 32bit systems if
- * the caller didn't specify O_LARGEFILE.
- */
-static int ext2_open_file (struct inode * inode, struct file * filp)
-{
-	if (inode->u.ext2_i.i_high_size && !(filp->f_flags & O_LARGEFILE))
-		return -EFBIG;
-	return 0;
-}
-#endif
-
 /*
  * We have mostly NULL's here: the current defaults are ok for
  * the ext2 filesystem.
@@ -146,11 +136,7 @@
 	NULL,			/* poll - default */
 	ext2_ioctl,		/* ioctl */
 	generic_file_mmap,	/* mmap */
-#if BITS_PER_LONG == 64	
 	NULL,			/* no special open is needed */
-#else
-	ext2_open_file,
-#endif
 	NULL,			/* flush */
 	ext2_release_file,	/* release */
 	ext2_sync_file,		/* fsync */
@@ -180,4 +166,31 @@
 	ext2_permission,	/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	ext2_pathconf,		/* pathconf */
 };
+
+long ext2_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return EXT2_NAME_LEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 64; /* FIXME: L-F-S:  mount-option: nolargefiles ? */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return EXT2_LINK_MAX;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
diff -ur linux-23027p1/fs/ext2/inode.c linux-23027p1m1/fs/ext2/inode.c
--- linux-23027p1/fs/ext2/inode.c	Fri Nov  5 19:57:30 1999
+++ linux-23027p1m1/fs/ext2/inode.c	Mon Nov  8 22:58:51 1999
@@ -216,14 +216,12 @@
 
 	/* Check file limits.. */
 	{
-		unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-		if (limit < RLIM_INFINITY) {
-			limit >>= EXT2_BLOCK_SIZE_BITS(inode->i_sb);
-			if (new_block >= limit) {
-				send_sig(SIGXFSZ, current, 0);
-				*err = -EFBIG;
-				return NULL;
-			}
+		u_long limit = (current->rlimfsz.rlim_cur >>
+				EXT2_BLOCK_SIZE_BITS(inode->i_sb));
+		if (new_block >= limit) {
+			send_sig(SIGXFSZ, current, 0);
+			*err = -EFBIG;
+			return NULL;
 		}
 	}
 
@@ -337,13 +335,14 @@
 	}
 	*err = -EFBIG;
 
-	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-	if (limit < RLIM_INFINITY) {
-		limit >>= EXT2_BLOCK_SIZE_BITS(inode->i_sb);
-		if (new_block >= limit) {
-			send_sig(SIGXFSZ, current, 0);
-			goto out;
-		}
+	/* "infinity" value is 2^63-1, shifting it down a few bits
+	   will stay so high that it doesn't matter.. */
+	limit = (current->rlimfsz.rlim_cur >>
+		 EXT2_BLOCK_SIZE_BITS(inode->i_sb));
+
+	if (new_block >= limit) {
+		send_sig(SIGXFSZ, current, 0);
+		goto out;
 	}
 
 	if (inode->u.ext2_i.i_next_alloc_block == new_block)
diff -ur linux-23027p1/fs/ext2/super.c linux-23027p1m1/fs/ext2/super.c
--- linux-23027p1/fs/ext2/super.c	Thu Oct 28 23:23:10 1999
+++ linux-23027p1m1/fs/ext2/super.c	Mon Nov  8 22:58:51 1999
@@ -128,7 +128,7 @@
 	NULL,
 	ext2_put_super,
 	ext2_write_super,
-	ext2_statfs,
+	ext2_statvfs,
 	ext2_remount
 };
 
@@ -750,10 +750,9 @@
 
 #endif
 
-int ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
+int ext2_statvfs (struct super_block * sb, struct statvfs64 * buf)
 {
 	unsigned long overhead;
-	struct statfs tmp;
 	int	ngroups, i;
 
 	if (test_opt (sb, MINIX_DF))
@@ -793,15 +792,15 @@
 			     (2 + sb->u.ext2_sb.s_itb_per_group));
 	}
 
-	tmp.f_type = EXT2_SUPER_MAGIC;
-	tmp.f_bsize = sb->s_blocksize;
-	tmp.f_blocks = le32_to_cpu(sb->u.ext2_sb.s_es->s_blocks_count) - overhead;
-	tmp.f_bfree = ext2_count_free_blocks (sb);
-	tmp.f_bavail = tmp.f_bfree - le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count);
-	if (tmp.f_bfree < le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count))
-		tmp.f_bavail = 0;
-	tmp.f_files = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
-	tmp.f_ffree = ext2_count_free_inodes (sb);
-	tmp.f_namelen = EXT2_NAME_LEN;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = EXT2_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = le32_to_cpu(sb->u.ext2_sb.s_es->s_blocks_count) - overhead;
+	buf->f_bfree = ext2_count_free_blocks (sb);
+	buf->f_bavail = buf->f_bfree - le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count);
+	if (buf->f_bfree < le32_to_cpu(sb->u.ext2_sb.s_es->s_r_blocks_count))
+		buf->f_bavail = 0;
+	buf->f_files = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
+	buf->f_ffree = ext2_count_free_inodes (sb);
+	buf->f_namelen = EXT2_NAME_LEN;
+	return 0;
 }
diff -ur linux-23027p1/fs/fat/fatfs_syms.c linux-23027p1m1/fs/fat/fatfs_syms.c
--- linux-23027p1/fs/fat/fatfs_syms.c	Tue Oct 26 21:21:46 1999
+++ linux-23027p1m1/fs/fat/fatfs_syms.c	Mon Nov  8 22:58:51 1999
@@ -43,7 +43,8 @@
 EXPORT_SYMBOL(fat_search_long);
 EXPORT_SYMBOL(fat_readdir);
 EXPORT_SYMBOL(fat_scan);
-EXPORT_SYMBOL(fat_statfs);
+EXPORT_SYMBOL(fat_statvfs);
+EXPORT_SYMBOL(fat_pathconf);
 EXPORT_SYMBOL(fat_uni2esc);
 EXPORT_SYMBOL(fat_unlock_creation);
 EXPORT_SYMBOL(fat_write_inode);
diff -ur linux-23027p1/fs/fat/file.c linux-23027p1m1/fs/fat/file.c
--- linux-23027p1/fs/fat/file.c	Sat Nov  6 02:27:28 1999
+++ linux-23027p1m1/fs/fat/file.c	Mon Nov  8 22:58:51 1999
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/pagemap.h>
 #include <linux/fat_cvf.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -64,7 +65,8 @@
 	fat_truncate,		/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	fat_statvfs,		/* statvfs */
 };
 
 ssize_t fat_file_read(
@@ -196,4 +198,31 @@
 	MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 	mark_inode_dirty(inode);
+}
+
+long fat_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  // FIXME: Detect VFAT operational mode of SB ! (namemax: 260)
+	  return 8+1+3;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/fat/inode.c linux-23027p1m1/fs/fat/inode.c
--- linux-23027p1/fs/fat/inode.c	Sat Nov  6 02:27:28 1999
+++ linux-23027p1m1/fs/fat/inode.c	Mon Nov  8 22:58:51 1999
@@ -413,7 +413,7 @@
 	fat_notify_change,
 	fat_put_super,
 	NULL,		/* write_super */
-	fat_statfs,
+	fat_statvfs,
 	NULL,		/* remount */
 	fat_clear_inode
 };
@@ -707,14 +707,13 @@
 	return NULL;
 }
 
-int fat_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
+int fat_statvfs(struct super_block *sb,struct statvfs64 *buf)
 {
 	int free,nr;
-	struct statfs tmp;
        
 	if (MSDOS_SB(sb)->cvf_format &&
-	    MSDOS_SB(sb)->cvf_format->cvf_statfs)
-		return MSDOS_SB(sb)->cvf_format->cvf_statfs(sb,buf,bufsiz);
+	    MSDOS_SB(sb)->cvf_format->cvf_statvfs)
+		return MSDOS_SB(sb)->cvf_format->cvf_statvfs(sb,buf);
 	  
 	lock_fat(sb);
 	if (MSDOS_SB(sb)->free_clusters != -1)
@@ -726,15 +725,15 @@
 		MSDOS_SB(sb)->free_clusters = free;
 	}
 	unlock_fat(sb);
-	tmp.f_type = sb->s_magic;
-	tmp.f_bsize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
-	tmp.f_blocks = MSDOS_SB(sb)->clusters;
-	tmp.f_bfree = free;
-	tmp.f_bavail = free;
-	tmp.f_files = 0;
-	tmp.f_ffree = 0;
-	tmp.f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = sb->s_magic;
+	buf->f_bsize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
+	buf->f_blocks = MSDOS_SB(sb)->clusters;
+	buf->f_bfree = free;
+	buf->f_bavail = free;
+	buf->f_files = 0;
+	buf->f_ffree = 0;
+	buf->f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
+	return 0;
 }
 
 static int is_exec(char *extension)
diff -ur linux-23027p1/fs/fcntl.c linux-23027p1m1/fs/fcntl.c
--- linux-23027p1/fs/fcntl.c	Mon Oct 11 20:13:25 1999
+++ linux-23027p1m1/fs/fcntl.c	Mon Nov  8 22:58:51 1999
@@ -215,6 +215,15 @@
 		case F_SETLKW:
 			err = fcntl_setlk(fd, cmd, (struct flock *) arg);
 			break;
+		case F_GETLK64:
+			err = fcntl_getlk64(fd, (struct flock64 *) arg);
+			break;
+		case F_SETLK64:
+			err = fcntl_setlk64(fd, cmd, (struct flock64 *) arg);
+			break;
+		case F_SETLKW64:
+			err = fcntl_setlk64(fd, cmd, (struct flock64 *) arg);
+			break;
 		case F_GETOWN:
 			/*
 			 * XXX If f_owner is a process group, the
diff -ur linux-23027p1/fs/fifo.c linux-23027p1m1/fs/fifo.c
--- linux-23027p1/fs/fifo.c	Tue Aug 24 20:12:00 1999
+++ linux-23027p1m1/fs/fifo.c	Mon Nov  8 22:58:51 1999
@@ -11,6 +11,7 @@
 
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 static int fifo_open(struct inode *inode, struct file *filp)
 {
@@ -187,7 +188,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	NULL,			/* pathconf */
 };
 
 
diff -ur linux-23027p1/fs/hfs/dir_cap.c linux-23027p1m1/fs/hfs/dir_cap.c
--- linux-23027p1/fs/hfs/dir_cap.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/dir_cap.c	Mon Nov  8 22:58:51 1999
@@ -94,7 +94,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 struct inode_operations hfs_cap_fdir_inode_operations = {
@@ -117,7 +118,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 struct inode_operations hfs_cap_rdir_inode_operations = {
@@ -140,7 +142,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ File-local functions ================*/
diff -ur linux-23027p1/fs/hfs/dir_dbl.c linux-23027p1m1/fs/hfs/dir_dbl.c
--- linux-23027p1/fs/hfs/dir_dbl.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/dir_dbl.c	Mon Nov  8 22:58:51 1999
@@ -93,7 +93,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 
diff -ur linux-23027p1/fs/hfs/dir_nat.c linux-23027p1m1/fs/hfs/dir_nat.c
--- linux-23027p1/fs/hfs/dir_nat.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/dir_nat.c	Mon Nov  8 22:58:51 1999
@@ -100,7 +100,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL                    /* revalidate */
+	NULL,                   /* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 struct inode_operations hfs_nat_hdir_inode_operations = {
@@ -123,7 +124,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL                    /* revalidate */
+	NULL,                   /* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ File-local functions ================*/
diff -ur linux-23027p1/fs/hfs/file.c linux-23027p1m1/fs/hfs/file.c
--- linux-23027p1/fs/hfs/file.c	Sat Nov  6 01:53:26 1999
+++ linux-23027p1m1/fs/hfs/file.c	Mon Nov  8 22:58:51 1999
@@ -20,6 +20,7 @@
 #include <linux/hfs_fs_sb.h>
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
+#include <linux/unistd.h>
 
 /*================ Forward declarations ================*/
 
@@ -70,7 +71,8 @@
 	hfs_file_truncate,	/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ Variable-like macros ================*/
@@ -544,4 +546,30 @@
 			}
 		}
 	}
+}
+
+long hfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return HFS_NAMELEN;
+	case _PC_NO_TRUNC:
+		return 0;
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return 1;	/* No classical UNIX links */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/hfs/file_cap.c linux-23027p1m1/fs/hfs/file_cap.c
--- linux-23027p1/fs/hfs/file_cap.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/file_cap.c	Mon Nov  8 22:58:51 1999
@@ -84,7 +84,8 @@
 	cap_info_truncate,		/* truncate */
 	NULL,				/* permission */
 	NULL,				/* smap */
-	NULL				/* revalidata */
+	NULL,				/* revalidata */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ File-local functions ================*/
diff -ur linux-23027p1/fs/hfs/file_hdr.c linux-23027p1m1/fs/hfs/file_hdr.c
--- linux-23027p1/fs/hfs/file_hdr.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/file_hdr.c	Mon Nov  8 22:58:51 1999
@@ -86,7 +86,8 @@
 	hdr_truncate,		/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 const struct hfs_hdr_layout hfs_dbl_fil_hdr_layout = {
diff -ur linux-23027p1/fs/hfs/hfs.h linux-23027p1m1/fs/hfs/hfs.h
--- linux-23027p1/fs/hfs/hfs.h	Mon Nov  8 17:25:29 1999
+++ linux-23027p1m1/fs/hfs/hfs.h	Mon Nov  8 22:58:51 1999
@@ -494,6 +494,9 @@
 extern void hfs_extent_adj(struct hfs_fork *);
 extern void hfs_extent_free(struct hfs_fork *);
 
+/* file.c */
+extern long hfs_pathconf(struct inode *, long);
+
 /* mdb.c */
 extern struct hfs_mdb *hfs_mdb_get(hfs_sysmdb, int, hfs_s32);
 extern void hfs_mdb_commit(struct hfs_mdb *, int);
diff -ur linux-23027p1/fs/hfs/super.c linux-23027p1m1/fs/hfs/super.c
--- linux-23027p1/fs/hfs/super.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/hfs/super.c	Mon Nov  8 22:58:51 1999
@@ -36,7 +36,7 @@
 
 static void hfs_read_inode(struct inode *);
 static void hfs_put_super(struct super_block *);
-static int hfs_statfs(struct super_block *, struct statfs *, int);
+static int hfs_statvfs(struct super_block *, struct statvfs64 *);
 static void hfs_write_super(struct super_block *);
 
 /*================ Global variables ================*/
@@ -49,7 +49,7 @@
 	hfs_notify_change,	/* notify_change - in inode.c */
 	hfs_put_super,		/* put_super */
 	hfs_write_super,	/* write_super */
-	hfs_statfs,		/* statfs */
+	hfs_statvfs,		/* statvfs */
 	NULL			/* remount_fs */
 };
 
@@ -136,29 +136,28 @@
 }
 
 /*
- * hfs_statfs()
+ * hfs_statvfs()
  *
- * This is the statfs() entry in the super_operations structure for
+ * This is the statvfs() entry in the super_operations structure for
  * HFS filesystems.  The purpose is to return various data about the
  * filesystem.
  *
  * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks.
  */
-static int hfs_statfs(struct super_block *sb, struct statfs *buf, int len)
+static int hfs_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
 	struct hfs_mdb *mdb = HFS_SB(sb)->s_mdb;
-	struct statfs tmp;
 
-	tmp.f_type = HFS_SUPER_MAGIC;
-	tmp.f_bsize = HFS_SECTOR_SIZE;
-	tmp.f_blocks = mdb->alloc_blksz * mdb->fs_ablocks;
-	tmp.f_bfree = mdb->alloc_blksz * mdb->free_ablocks;
-	tmp.f_bavail = tmp.f_bfree;
-	tmp.f_files = mdb->fs_ablocks;  
-	tmp.f_ffree = mdb->free_ablocks;
-	tmp.f_namelen = HFS_NAMELEN;
+	buf->f_type = HFS_SUPER_MAGIC;
+	buf->f_bsize = HFS_SECTOR_SIZE;
+	buf->f_blocks = mdb->alloc_blksz * mdb->fs_ablocks;
+	buf->f_bfree = mdb->alloc_blksz * mdb->free_ablocks;
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = mdb->fs_ablocks;  
+	buf->f_ffree = mdb->free_ablocks;
+	buf->f_namelen = HFS_NAMELEN;
 
-	return copy_to_user(buf, &tmp, len) ? -EFAULT : 0;
+	return 0;
 }
 
 /*
diff -ur linux-23027p1/fs/hpfs/file.c linux-23027p1m1/fs/hpfs/file.c
--- linux-23027p1/fs/hpfs/file.c	Tue Oct 26 21:23:31 1999
+++ linux-23027p1m1/fs/hpfs/file.c	Mon Nov  8 22:58:51 1999
@@ -94,9 +94,10 @@
 	struct page * page_cache = NULL;
 	long status;
 
-	printk("- off: %08x\n", (int)page->offset);
-	pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK;
-	while (pgpos < page->offset) {
+	printk("- off: %Ld\n", (((loff_t)page->index) << PAGE_CACHE_SHIFT));
+	/* Blocks are 512 byte entities */
+	pgpos = (inode->i_blocks - 1) >> (PAGE_CACHE_SHIFT - 9);
+	while (pgpos < page->index) {
 long pgp = pgpos;
 		printk("pgpos: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks);
 		hash = page_hash(&inode->i_data, pgpos);
diff -ur linux-23027p1/fs/hpfs/super.c linux-23027p1m1/fs/hpfs/super.c
--- linux-23027p1/fs/hpfs/super.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hpfs/super.c	Mon Nov  8 22:58:51 1999
@@ -132,22 +132,21 @@
 	return count;
 }
 
-int hpfs_statfs(struct super_block *s, struct statfs *buf, int bufsiz)
+int hpfs_statvfs(struct super_block *s, struct statvfs64 *buf)
 {
-	struct statfs tmp;
 	/*if (s->s_hpfs_n_free == -1) {*/
 		s->s_hpfs_n_free = count_bitmaps(s);
 		s->s_hpfs_n_free_dnodes = hpfs_count_one_bitmap(s, s->s_hpfs_dmap);
 	/*}*/
-	tmp.f_type = s->s_magic;
-	tmp.f_bsize = 512;
-	tmp.f_blocks = s->s_hpfs_fs_size;
-	tmp.f_bfree = s->s_hpfs_n_free;
-	tmp.f_bavail = s->s_hpfs_n_free;
-	tmp.f_files = s->s_hpfs_dirband_size / 4;
-	tmp.f_ffree = s->s_hpfs_n_free_dnodes;
-	tmp.f_namelen = 254;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = s->s_magic;
+	buf->f_bsize = 512;
+	buf->f_blocks = s->s_hpfs_fs_size;
+	buf->f_bfree = s->s_hpfs_n_free;
+	buf->f_bavail = s->s_hpfs_n_free;
+	buf->f_files = s->s_hpfs_dirband_size / 4;
+	buf->f_ffree = s->s_hpfs_n_free_dnodes;
+	buf->f_namelen = 254;
+	return 0;
 }
 
 /* Super operations */
@@ -161,7 +160,7 @@
         hpfs_notify_change,		/* notify_change */
         hpfs_put_super,			/* put_super */
         NULL,				/* write_super */
-        hpfs_statfs,			/* statfs */
+        hpfs_statvfs,			/* statvfs */
         hpfs_remount_fs,		/* remount_fs */
 	NULL,				/* clear inode */
 	NULL,				/* umount_begin */
diff -ur linux-23027p1/fs/isofs/dir.c linux-23027p1m1/fs/isofs/dir.c
--- linux-23027p1/fs/isofs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/isofs/dir.c	Mon Nov  8 22:58:51 1999
@@ -21,11 +21,39 @@
 #include <linux/sched.h>
 #include <linux/locks.h>
 #include <linux/config.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
 static int isofs_readdir(struct file *, void *, filldir_t);
 
+long isofs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		break;	/* This is read-only filesystem! */
+	case _PC_NO_TRUNC:
+		break;	/* This is read-only filesystem! */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32; // FIXME: DVD-XXX ???
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		break;	/* This is read-only filesystem! */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
+
 static struct file_operations isofs_dir_operations =
 {
 	NULL,			/* lseek - default */
@@ -64,7 +92,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	isofs_pathconf,		/* pathconf */
 };
 
 static int isofs_name_translate(char * old, int len, char * new)
diff -ur linux-23027p1/fs/isofs/file.c linux-23027p1m1/fs/isofs/file.c
--- linux-23027p1/fs/isofs/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/isofs/file.c	Mon Nov  8 22:58:51 1999
@@ -17,6 +17,8 @@
 #include <linux/locks.h>
 #include <linux/fs.h>
 
+extern long isofs_pathconf(struct inode *, long);
+
 /*
  * We have mostly NULLs here: the current defaults are OK for
  * the isofs filesystem.
@@ -55,5 +57,6 @@
 	NULL,	       		/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	isofs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/isofs/inode.c linux-23027p1m1/fs/isofs/inode.c
--- linux-23027p1/fs/isofs/inode.c	Fri Nov  5 01:50:50 1999
+++ linux-23027p1m1/fs/isofs/inode.c	Mon Nov  8 22:58:51 1999
@@ -74,7 +74,7 @@
 }
 
 static void isofs_read_inode(struct inode *);
-static int isofs_statfs (struct super_block *, struct statfs *, int);
+static int isofs_statvfs (struct super_block *, struct statvfs64 *);
 
 static struct super_operations isofs_sops = {
 	isofs_read_inode,
@@ -84,7 +84,7 @@
 	NULL,			/* notify_change */
 	isofs_put_super,
 	NULL,			/* write_super */
-	isofs_statfs,
+	isofs_statvfs,
 	NULL
 };
 
@@ -905,20 +905,18 @@
 	return NULL;
 }
 
-static int isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
+static int isofs_statvfs (struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	tmp.f_type = ISOFS_SUPER_MAGIC;
-	tmp.f_bsize = sb->s_blocksize;
-	tmp.f_blocks = (sb->u.isofs_sb.s_nzones
+	buf->f_type = ISOFS_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = (sb->u.isofs_sb.s_nzones
                   << (sb->u.isofs_sb.s_log_zone_size - sb->s_blocksize_bits));
-	tmp.f_bfree = 0;
-	tmp.f_bavail = 0;
-	tmp.f_files = sb->u.isofs_sb.s_ninodes;
-	tmp.f_ffree = 0;
-	tmp.f_namelen = NAME_MAX;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_bfree = 0;
+	buf->f_bavail = 0;
+	buf->f_files = sb->u.isofs_sb.s_ninodes;
+	buf->f_ffree = 0;
+	buf->f_namelen = NAME_MAX;
+	return 0;
 }
 
 /* Life is simpler than for other filesystem since we never
@@ -1008,8 +1006,8 @@
 	goto abort;
 
 abort_beyond_end:
-	printk("_isofs_bmap: block >= EOF (%ld, %ld)\n",
-	       iblock, (unsigned long) inode->i_size);
+	printk("_isofs_bmap: block >= EOF (%ld, %Ld)\n",
+	       iblock, inode->i_size);
 	goto abort;
 
 abort_too_many_sections:
@@ -1228,7 +1226,7 @@
 #endif
 
 #ifdef DEBUG
-	printk("Get inode %x: %d %d: %d\n",inode->i_ino, block,
+	printk("Get inode %x: %d %d: %Ld\n",inode->i_ino, block,
 	       ((int)pnt) & 0x3ff, inode->i_size);
 #endif
 
diff -ur linux-23027p1/fs/lockd/svclock.c linux-23027p1m1/fs/lockd/svclock.c
--- linux-23027p1/fs/lockd/svclock.c	Mon Aug 23 20:16:34 1999
+++ linux-23027p1m1/fs/lockd/svclock.c	Mon Nov  8 22:58:51 1999
@@ -93,12 +93,12 @@
 	struct nlm_block	**head, *block;
 	struct file_lock	*fl;
 
-	dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %ld-%ld ty=%d\n",
+	dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
 				file, lock->fl.fl_pid, lock->fl.fl_start,
 				lock->fl.fl_end, lock->fl.fl_type);
 	for (head = &nlm_blocked; (block = *head); head = &block->b_next) {
 		fl = &block->b_call.a_args.lock.fl;
-		dprintk("       check f=%p pd=%d %ld-%ld ty=%d\n",
+		dprintk("       check f=%p pd=%d %Ld-%Ld ty=%d\n",
 				block->b_file, fl->fl_pid, fl->fl_start,
 				fl->fl_end, fl->fl_type);
 		if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) {
@@ -282,7 +282,7 @@
 	struct nlm_block	*block;
 	int			error;
 
-	dprintk("lockd: nlmsvc_lock(%04x/%ld, ty=%d, pi=%d, %ld-%ld, bl=%d)\n",
+	dprintk("lockd: nlmsvc_lock(%04x/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
 				file->f_file.f_dentry->d_inode->i_dev,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_type, lock->fl.fl_pid,
@@ -355,7 +355,7 @@
 {
 	struct file_lock	*fl;
 
-	dprintk("lockd: nlmsvc_testlock(%04x/%ld, ty=%d, %ld-%ld)\n",
+	dprintk("lockd: nlmsvc_testlock(%04x/%ld, ty=%d, %Ld-%Ld)\n",
 				file->f_file.f_dentry->d_inode->i_dev,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_type,
@@ -363,7 +363,7 @@
 				lock->fl.fl_end);
 
 	if ((fl = posix_test_lock(&file->f_file, &lock->fl)) != NULL) {
-		dprintk("lockd: conflicting lock(ty=%d, %ld-%ld)\n",
+		dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
 				fl->fl_type, fl->fl_start, fl->fl_end);
 		conflock->caller = "somehost";	/* FIXME */
 		conflock->oh.len = 0;		/* don't return OH info */
@@ -386,7 +386,7 @@
 {
 	int	error;
 
-	dprintk("lockd: nlmsvc_unlock(%04x/%ld, pi=%d, %ld-%ld)\n",
+	dprintk("lockd: nlmsvc_unlock(%04x/%ld, pi=%d, %Ld-%Ld)\n",
 				file->f_file.f_dentry->d_inode->i_dev,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_pid,
@@ -414,7 +414,7 @@
 {
 	struct nlm_block	*block;
 
-	dprintk("lockd: nlmsvc_cancel(%04x/%ld, pi=%d, %ld-%ld)\n",
+	dprintk("lockd: nlmsvc_cancel(%04x/%ld, pi=%d, %Ld-%Ld)\n",
 				file->f_file.f_dentry->d_inode->i_dev,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_pid,
diff -ur linux-23027p1/fs/lockd/xdr.c linux-23027p1m1/fs/lockd/xdr.c
--- linux-23027p1/fs/lockd/xdr.c	Sat Feb  6 22:46:21 1999
+++ linux-23027p1m1/fs/lockd/xdr.c	Mon Nov  8 22:58:51 1999
@@ -142,7 +142,7 @@
 	fl->fl_pid   = ntohl(*p++);
 	fl->fl_flags = FL_POSIX;
 	fl->fl_type  = F_RDLCK;		/* as good as anything else */
-	fl->fl_start = ntohl(*p++);
+	fl->fl_start = (u_long)ntohl(*p++); // Up to 4G-1
 	len = ntohl(*p++);
 	if (len == 0 || (fl->fl_end = fl->fl_start + len - 1) < 0)
 		fl->fl_end = NLM_OFFSET_MAX;
@@ -163,11 +163,11 @@
 		return NULL;
 
 	*p++ = htonl(fl->fl_pid);
-	*p++ = htonl(lock->fl.fl_start);
+	*p++ = htonl((u_long)lock->fl.fl_start);
 	if (lock->fl.fl_end == NLM_OFFSET_MAX)
 		*p++ = xdr_zero;
 	else
-		*p++ = htonl(lock->fl.fl_end - lock->fl.fl_start + 1);
+		*p++ = htonl((u_long)(lock->fl.fl_end - lock->fl.fl_start + 1));
 
 	return p;
 }
@@ -192,11 +192,11 @@
 		if (!(p = xdr_encode_netobj(p, &resp->lock.oh)))
 			return 0;
 
-		*p++ = htonl(fl->fl_start);
+		*p++ = htonl((u_long)fl->fl_start);
 		if (fl->fl_end == NLM_OFFSET_MAX)
 			*p++ = xdr_zero;
 		else
-			*p++ = htonl(fl->fl_end - fl->fl_start + 1);
+			*p++ = htonl((u_long)(fl->fl_end - fl->fl_start + 1));
 	}
 
 	return p;
@@ -425,7 +425,7 @@
 
 		fl->fl_flags = FL_POSIX;
 		fl->fl_type  = excl? F_WRLCK : F_RDLCK;
-		fl->fl_start = ntohl(*p++);
+		fl->fl_start = (u_long)ntohl(*p++);
 		len = ntohl(*p++);
 		if (len == 0 || (fl->fl_end = fl->fl_start + len - 1) < 0)
 			fl->fl_end = NLM_OFFSET_MAX;
diff -ur linux-23027p1/fs/locks.c linux-23027p1m1/fs/locks.c
--- linux-23027p1/fs/locks.c	Mon Aug 23 21:15:53 1999
+++ linux-23027p1m1/fs/locks.c	Mon Nov  8 22:58:51 1999
@@ -111,12 +111,12 @@
 
 #include <asm/uaccess.h>
 
-#define OFFSET_MAX	((off_t)LONG_MAX)	/* FIXME: move elsewhere? */
+#define OFFSET_MAX	((loff_t)((~0ULL)>>1))	/* FIXME: move elsewhere? */
 
 static int flock_make_lock(struct file *filp, struct file_lock *fl,
 			       unsigned int cmd);
 static int posix_make_lock(struct file *filp, struct file_lock *fl,
-			       struct flock *l);
+			       struct flock64 *l);
 static int flock_locks_conflict(struct file_lock *caller_fl,
 				struct file_lock *sys_fl);
 static int posix_locks_conflict(struct file_lock *caller_fl,
@@ -195,7 +195,7 @@
 
 	if (waiter->fl_prevblock) {
 		printk(KERN_ERR "locks_insert_block: remove duplicated lock "
-			"(pid=%d %ld-%ld type=%d)\n",
+			"(pid=%d %Ld-%Ld type=%d)\n",
 			waiter->fl_pid, waiter->fl_start,
 			waiter->fl_end, waiter->fl_type);
 		locks_delete_block(waiter->fl_prevblock, waiter);
@@ -323,7 +323,192 @@
 {
 	struct file *filp;
 	struct file_lock *fl,file_lock;
-	struct flock flock;
+	int error = -EFAULT;
+
+	struct flock flock32;
+	struct flock64 flock;
+
+	if (copy_from_user(&flock32, l, sizeof(flock32)))
+		goto out;
+	error = -EINVAL;
+	if ((flock32.l_type != F_RDLCK) && (flock32.l_type != F_WRLCK))
+		goto out;
+	/* Convert to 64-bit offsets for internal use */
+	flock.l_type   = flock32.l_type;
+	flock.l_whence = flock32.l_whence;
+	flock.l_start  = (u_long)flock32.l_start;
+	flock.l_len    = (u_long)flock32.l_len;
+	flock.l_pid    = flock32.l_pid;
+
+	error = -EBADF;
+	filp = fget(fd);
+	if (!filp)
+		goto out;
+
+	error = -EINVAL;
+	if (!filp->f_dentry || !filp->f_dentry->d_inode)
+		goto out_putf;
+
+	if (!posix_make_lock(filp, &file_lock, &flock))
+		goto out_putf;
+
+	if (filp->f_op->lock) {
+		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
+		if (error < 0)
+			goto out_putf;
+		fl = &file_lock;
+	} else {
+		fl = posix_test_lock(filp, &file_lock);
+	}
+ 
+	flock.l_type = F_UNLCK;
+	if (fl != NULL) {
+		flock.l_pid = fl->fl_pid;
+		flock.l_start = fl->fl_start;
+		flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
+			fl->fl_end - fl->fl_start + 1;
+		flock.l_whence = 0;
+		flock.l_type = fl->fl_type;
+	}
+
+	/* Convert to 32-bit offsets (at 32-bit systems) */
+
+	if (!off_t_presentable(flock.l_start) ||
+	    !off_t_presentable(flock.l_len) ||
+	    !off_t_presentable(flock.l_start + flock.l_len)) {
+		error = -EOVERFLOW;
+		goto out_putf;
+	}
+
+	flock32.l_type   = flock.l_type;
+	flock32.l_whence = flock.l_whence;
+	flock32.l_start  = flock.l_start;
+	flock32.l_len    = flock.l_len;
+	flock32.l_pid    = flock.l_pid;
+
+	error = -EFAULT;
+	if (!copy_to_user(l, &flock32, sizeof(flock32)))
+		error = 0;
+  
+out_putf:
+	fput(filp);
+out:
+	return error;
+}
+
+/* Apply the lock described by l to an open file descriptor.
+ * This implements both the F_SETLK and F_SETLKW commands of fcntl().
+ */
+int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
+{
+	struct file *filp;
+	struct file_lock file_lock;
+	struct flock64 flock;
+	struct flock flock32;
+	struct dentry * dentry;
+	struct inode *inode;
+	int error;
+
+	/*
+	 * This might block, so we do it before checking the inode.
+	 */
+	error = -EFAULT;
+	if (copy_from_user(&flock32, l, sizeof(flock32)))
+		goto out;
+	/* Convert to 64-bit offsets for internal use */
+	flock.l_type   = flock32.l_type;
+	flock.l_whence = flock32.l_whence;
+	flock.l_start  = (u_long)flock32.l_start;
+	flock.l_len    = (u_long)flock32.l_len;
+	flock.l_pid    = flock32.l_pid;
+
+	/* Get arguments and validate them ...
+	 */
+
+	error = -EBADF;
+	filp = fget(fd);
+	if (!filp)
+		goto out;
+
+	error = -EINVAL;
+	if (!(dentry = filp->f_dentry))
+		goto out_putf;
+	if (!(inode = dentry->d_inode))
+		goto out_putf;
+
+	/* Don't allow mandatory locks on files that may be memory mapped
+	 * and shared.
+	 */
+	if (IS_MANDLOCK(inode) &&
+	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
+	    inode->i_mmap) {
+		struct vm_area_struct *vma = inode->i_mmap;
+		error = -EAGAIN;
+		do {
+			if (vma->vm_flags & VM_MAYSHARE)
+				goto out_putf;
+		} while ((vma = vma->vm_next_share) != NULL);
+	}
+
+	error = -EINVAL;
+	if (!posix_make_lock(filp, &file_lock, &flock))
+		goto out_putf;
+	
+	error = -EBADF;
+	switch (flock.l_type) {
+	case F_RDLCK:
+		if (!(filp->f_mode & FMODE_READ))
+			goto out_putf;
+		break;
+	case F_WRLCK:
+		if (!(filp->f_mode & FMODE_WRITE))
+			goto out_putf;
+		break;
+	case F_UNLCK:
+		break;
+	case F_SHLCK:
+	case F_EXLCK:
+#ifdef __sparc__
+/* warn a bit for now, but don't overdo it */
+{
+	static int count = 0;
+	if (!count) {
+		count=1;
+		printk(KERN_WARNING
+		       "fcntl_setlk() called by process %d (%s) with broken flock() emulation\n",
+		       current->pid, current->comm);
+	}
+}
+		if (!(filp->f_mode & 3))
+			goto out_putf;
+		break;
+#endif
+	default:
+		error = -EINVAL;
+		goto out_putf;
+	}
+
+	if (filp->f_op->lock != NULL) {
+		error = filp->f_op->lock(filp, cmd, &file_lock);
+		if (error < 0)
+			goto out_putf;
+	}
+	error = posix_lock_file(filp, &file_lock, cmd == F_SETLKW);
+
+out_putf:
+	fput(filp);
+out:
+	return error;
+}
+
+/* Report the first existing lock that would conflict with l.
+ * This implements the F_GETLK command of fcntl().
+ */
+int fcntl_getlk64(unsigned int fd, struct flock64 *l)
+{
+	struct file *filp;
+	struct file_lock *fl,file_lock;
+	struct flock64 flock;
 	int error;
 
 	error = -EFAULT;
@@ -380,11 +565,11 @@
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
-int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
+int fcntl_setlk64(unsigned int fd, unsigned int cmd, struct flock64 *l)
 {
 	struct file *filp;
 	struct file_lock file_lock;
-	struct flock flock;
+	struct flock64 flock;
 	struct dentry * dentry;
 	struct inode *inode;
 	int error;
@@ -647,9 +832,9 @@
  * style lock.
  */
 static int posix_make_lock(struct file *filp, struct file_lock *fl,
-			   struct flock *l)
+			   struct flock64 *l)
 {
-	off_t start;
+	loff_t start;
 
 	memset(fl, 0, sizeof(*fl));
 	
@@ -1200,7 +1385,7 @@
 		p += sprintf(p, "FLOCK  ADVISORY  ");
 	}
 	p += sprintf(p, "%s ", (fl->fl_type == F_RDLCK) ? "READ " : "WRITE");
-	p += sprintf(p, "%d %s:%ld %ld %ld ",
+	p += sprintf(p, "%d %s:%ld %Ld %Ld ",
 		     fl->fl_pid,
 		     kdevname(inode->i_dev), inode->i_ino, fl->fl_start,
 		     fl->fl_end);
diff -ur linux-23027p1/fs/minix/dir.c linux-23027p1m1/fs/minix/dir.c
--- linux-23027p1/fs/minix/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/minix/dir.c	Mon Nov  8 22:58:51 1999
@@ -21,6 +21,7 @@
 }
 
 static int minix_readdir(struct file *, void *, filldir_t);
+extern long minix_pathconf(struct inode *, long);
 
 static struct file_operations minix_dir_operations = {
 	NULL,			/* lseek - default */
@@ -59,7 +60,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	minix_pathconf,		/* pathconf */
 };
 
 static int minix_readdir(struct file * filp,
diff -ur linux-23027p1/fs/minix/file.c linux-23027p1m1/fs/minix/file.c
--- linux-23027p1/fs/minix/file.c	Fri Jul 23 20:30:42 1999
+++ linux-23027p1m1/fs/minix/file.c	Mon Nov  8 22:58:51 1999
@@ -14,6 +14,7 @@
 #include <linux/locks.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -26,6 +27,34 @@
 #include <linux/fs.h>
 #include <linux/minix_fs.h>
 
+long minix_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return inode->i_sb->u.minix_sb.s_namelen;
+
+	case _PC_NO_TRUNC:
+		return 1;		/* UNIX semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return inode->i_sb->u.minix_sb.s_link_max;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
+
 /*
  * Write to a file (through the page cache).
  */
@@ -78,4 +107,5 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	minix_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/minix/inode.c linux-23027p1m1/fs/minix/inode.c
--- linux-23027p1/fs/minix/inode.c	Tue Aug 31 21:23:03 1999
+++ linux-23027p1m1/fs/minix/inode.c	Mon Nov  8 22:58:51 1999
@@ -29,7 +29,7 @@
 
 static void minix_read_inode(struct inode * inode);
 static void minix_write_inode(struct inode * inode);
-static int minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static int minix_statvfs(struct super_block *sb, struct statvfs64 *buf);
 static int minix_remount (struct super_block * sb, int * flags, char * data);
 
 static void minix_delete_inode(struct inode *inode)
@@ -87,7 +87,7 @@
 	NULL,			/* notify_change */
 	minix_put_super,
 	minix_write_super,
-	minix_statfs,
+	minix_statvfs,
 	minix_remount
 };
 
@@ -331,19 +331,17 @@
 	return NULL;
 }
 
-static int minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int minix_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	tmp.f_type = sb->s_magic;
-	tmp.f_bsize = sb->s_blocksize;
-	tmp.f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size;
-	tmp.f_bfree = minix_count_free_blocks(sb);
-	tmp.f_bavail = tmp.f_bfree;
-	tmp.f_files = sb->u.minix_sb.s_ninodes;
-	tmp.f_ffree = minix_count_free_inodes(sb);
-	tmp.f_namelen = sb->u.minix_sb.s_namelen;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = sb->s_magic;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size;
+	buf->f_bfree = minix_count_free_blocks(sb);
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = sb->u.minix_sb.s_ninodes;
+	buf->f_ffree = minix_count_free_inodes(sb);
+	buf->f_namelen = sb->u.minix_sb.s_namelen;
+	return 0;
 }
 
 /*
diff -ur linux-23027p1/fs/minix/symlink.c linux-23027p1m1/fs/minix/symlink.c
--- linux-23027p1/fs/minix/symlink.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/minix/symlink.c	Mon Nov  8 22:58:51 1999
@@ -16,6 +16,7 @@
 
 static int minix_readlink(struct dentry *, char *, int);
 static struct dentry *minix_follow_link(struct dentry *, struct dentry *, unsigned int);
+extern long minix_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -40,7 +41,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	minix_pathconf,		/* pathconf */
 };
 
 static struct dentry * minix_follow_link(struct dentry * dentry,
diff -ur linux-23027p1/fs/msdos/namei.c linux-23027p1m1/fs/msdos/namei.c
--- linux-23027p1/fs/msdos/namei.c	Tue Aug 31 21:23:03 1999
+++ linux-23027p1m1/fs/msdos/namei.c	Mon Nov  8 22:58:51 1999
@@ -583,6 +583,8 @@
 }
 
 
+extern long fat_pathconf(struct inode *, long);
+
 /* The public inode operations for the msdos fs */
 struct inode_operations msdos_dir_inode_operations = {
 	&fat_dir_operations,	/* default directory file-ops */
@@ -605,6 +607,7 @@
 	NULL,			/* permission */
 	NULL,                   /* smap */
 	NULL,                   /* revalidate */
+	fat_pathconf,		/* pathconf */
 };
 
 static void msdos_put_super_callback(struct super_block *sb)
diff -ur linux-23027p1/fs/ncpfs/dir.c linux-23027p1m1/fs/ncpfs/dir.c
--- linux-23027p1/fs/ncpfs/dir.c	Mon Nov  1 20:31:34 1999
+++ linux-23027p1m1/fs/ncpfs/dir.c	Mon Nov  8 22:58:51 1999
@@ -45,6 +45,8 @@
 extern int ncp_symlink(struct inode *, struct dentry *, const char *);
 #endif
 		      
+extern long ncp_pathconf(struct inode *, long);
+
 static struct file_operations ncp_dir_operations =
 {
 	NULL,			/* lseek - default */
@@ -86,6 +88,7 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	ncp_pathconf,		/* pathconf */
 };
 
 static ssize_t 
diff -ur linux-23027p1/fs/ncpfs/file.c linux-23027p1m1/fs/ncpfs/file.c
--- linux-23027p1/fs/ncpfs/file.c	Fri Oct 29 20:53:32 1999
+++ linux-23027p1m1/fs/ncpfs/file.c	Mon Nov  8 22:58:51 1999
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/locks.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
@@ -94,7 +95,7 @@
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	size_t already_read = 0;
-	off_t pos;
+	loff_t pos;
 	size_t bufsize;
 	int error;
 	void* freepage;
@@ -145,7 +146,7 @@
 	/* First read in as much as possible for each bufsize. */
 	while (already_read < count) {
 		int read_this_time;
-		size_t to_read = min(bufsize - (pos % bufsize),
+		size_t to_read = min(bufsize - (pos & (bufsize -1)),
 				  count - already_read);
 
 		error = ncp_read_bounce(NCP_SERVER(inode),
@@ -185,7 +186,7 @@
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	size_t already_written = 0;
-	off_t pos;
+	loff_t pos;
 	size_t bufsize;
 	int errno;
 	void* bouncebuffer;
@@ -222,12 +223,18 @@
 
 	already_written = 0;
 
+	/* Maximum file size: 2G-1 */
+	if (pos >= 0x7fffffffULL)
+		return -EFBIG;
+	if ((pos + count) >= 0x7fffffffULL)
+		count = 0x7fffffffULL - pos;
+
 	bouncebuffer = kmalloc(bufsize, GFP_NFS);
 	if (!bouncebuffer)
 		return -EIO;	/* -ENOMEM */
 	while (already_written < count) {
 		int written_this_time;
-		size_t to_write = min(bufsize - (pos % bufsize),
+		size_t to_write = min(bufsize - (pos & (bufsize -1)),
 				   count - already_written);
 
 		if (copy_from_user(bouncebuffer, buf, to_write)) {
@@ -262,6 +269,34 @@
 	return already_written ? already_written : errno;
 }
 
+ 
+long ncp_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return NCP_MAXNAMELEN; /* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* varies per server.. */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
+
 static struct file_operations ncp_file_operations =
 {
 	NULL,			/* lseek - default */
@@ -298,5 +333,6 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ncp_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/ncpfs/inode.c linux-23027p1m1/fs/ncpfs/inode.c
--- linux-23027p1/fs/ncpfs/inode.c	Sat Nov  6 00:22:05 1999
+++ linux-23027p1m1/fs/ncpfs/inode.c	Mon Nov  8 22:58:51 1999
@@ -34,7 +34,7 @@
 static void ncp_put_inode(struct inode *);
 static void ncp_delete_inode(struct inode *);
 static void ncp_put_super(struct super_block *);
-static int  ncp_statfs(struct super_block *, struct statfs *, int);
+static int  ncp_statvfs(struct super_block *, struct statvfs64 *);
 
 static struct super_operations ncp_sops =
 {
@@ -45,7 +45,7 @@
 	ncp_notify_change,	/* notify change */
 	ncp_put_super,		/* put superblock */
 	NULL,			/* write superblock */
-	ncp_statfs,		/* stat filesystem */
+	ncp_statvfs,		/* stat filesystem */
 	NULL                    /* remount */
 };
 
@@ -485,25 +485,23 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static int ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int ncp_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
 	/* We cannot say how much disk space is left on a mounted
 	   NetWare Server, because free space is distributed over
 	   volumes, and the current user might have disk quotas. So
 	   free space is not that simple to determine. Our decision
 	   here is to err conservatively. */
 
-	tmp.f_type = NCP_SUPER_MAGIC;
-	tmp.f_bsize = NCP_BLOCK_SIZE;
-	tmp.f_blocks = 0;
-	tmp.f_bfree = 0;
-	tmp.f_bavail = 0;
-	tmp.f_files = -1;
-	tmp.f_ffree = -1;
-	tmp.f_namelen = 12;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = NCP_SUPER_MAGIC;
+	buf->f_bsize = NCP_BLOCK_SIZE;
+	buf->f_blocks = 0;
+	buf->f_bfree = 0;
+	buf->f_bavail = 0;
+	buf->f_files = -1;
+	buf->f_ffree = -1;
+	buf->f_namelen = 12;
+	return 0;
 }
 
 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
diff -ur linux-23027p1/fs/nfs/dir.c linux-23027p1m1/fs/nfs/dir.c
--- linux-23027p1/fs/nfs/dir.c	Sat Oct 30 19:37:26 1999
+++ linux-23027p1m1/fs/nfs/dir.c	Mon Nov  8 22:58:51 1999
@@ -50,6 +50,7 @@
 static int nfs_mknod(struct inode *, struct dentry *, int, int);
 static int nfs_rename(struct inode *, struct dentry *,
 		      struct inode *, struct dentry *);
+extern long nfs_pathconf(struct inode *, long);
 
 static struct file_operations nfs_dir_operations = {
 	NULL,			/* lseek - default */
@@ -86,6 +87,7 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	nfs_revalidate,		/* revalidate */
+	nfs_pathconf,		/* pathconf */
 };
 
 static ssize_t
diff -ur linux-23027p1/fs/nfs/file.c linux-23027p1m1/fs/nfs/file.c
--- linux-23027p1/fs/nfs/file.c	Fri Oct 15 00:22:09 1999
+++ linux-23027p1m1/fs/nfs/file.c	Mon Nov  8 22:58:51 1999
@@ -27,6 +27,7 @@
 #include <linux/pagemap.h>
 #include <linux/lockd/bind.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/segment.h>
@@ -39,6 +40,7 @@
 static ssize_t nfs_file_write(struct file *, const char *, size_t, loff_t *);
 static int  nfs_file_flush(struct file *);
 static int  nfs_fsync(struct file *, struct dentry *dentry);
+extern long nfs_pathconf(struct inode *, long);
 
 static struct file_operations nfs_file_operations = {
 	NULL,			/* lseek - default */
@@ -116,6 +118,11 @@
 		dentry->d_parent->d_name.name, dentry->d_name.name,
 		(unsigned long) count, (unsigned long) *ppos);
 
+	/* Unconditionally allow only up to 2G files */
+	/* FIXME: NFSv3 could allow 64-bit file offsets! */
+	if ((*ppos+1LL) >= 0x7fffffffLL)
+		return -EOVERFLOW;
+
 	result = nfs_revalidate_inode(NFS_DSERVER(dentry), dentry);
 	if (!result)
 		result = generic_file_read(file, buf, count, ppos);
@@ -191,9 +198,16 @@
 	struct inode * inode = dentry->d_inode;
 	ssize_t result;
 
-	dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n",
+	dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		inode->i_ino, (unsigned long) count, (unsigned long) *ppos);
+		inode->i_ino, (unsigned long) count, *ppos);
+
+	/* Unconditionally allow only up to 2G files */
+	/* FIXME: NFSv3 could allow 64-bit file offsets! */
+	if ((*ppos+1LL) > 0x7fffffffLL) {
+		result = -EOVERFLOW;
+		goto out;
+	}
 
 	result = -EBUSY;
 	if (IS_SWAPFILE(inode))
@@ -224,7 +238,7 @@
 	struct inode * inode = filp->f_dentry->d_inode;
 	int	status = 0;
 
-	dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n",
+	dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n",
 			inode->i_dev, inode->i_ino,
 			fl->fl_type, fl->fl_flags,
 			fl->fl_start, fl->fl_end);
@@ -273,4 +287,32 @@
  out_ok:
 	NFS_CACHEINV(inode);
 	return status;
+}
+
+
+long nfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return -INT_MAX; /* Unknown */
+
+	case _PC_NO_TRUNC:
+		return -INT_MAX; /* Unknown */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;	 /* NFSv3 would allow 64-bit sizes */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return -INT_MAX; /* Unknown */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/nfs/inode.c linux-23027p1m1/fs/nfs/inode.c
--- linux-23027p1/fs/nfs/inode.c	Fri Nov  5 01:48:15 1999
+++ linux-23027p1m1/fs/nfs/inode.c	Mon Nov  8 22:58:51 1999
@@ -46,7 +46,7 @@
 static int  nfs_notify_change(struct dentry *, struct iattr *);
 static void nfs_put_super(struct super_block *);
 static void nfs_umount_begin(struct super_block *);
-static int  nfs_statfs(struct super_block *, struct statfs *, int);
+static int  nfs_statvfs(struct super_block *, struct statvfs64 *);
 
 static struct super_operations nfs_sops = { 
 	nfs_read_inode,		/* read inode */
@@ -56,7 +56,7 @@
 	nfs_notify_change,	/* notify change */
 	nfs_put_super,		/* put superblock */
 	NULL,			/* write superblock */
-	nfs_statfs,		/* stat filesystem */
+	nfs_statvfs,		/* stat filesystem */
 	NULL,			/* no remount */
 	NULL,			/* no clear inode */
 	nfs_umount_begin	/* umount attempt begin */
@@ -370,27 +370,26 @@
 }
 
 static int
-nfs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+nfs_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
 	int error;
 	struct nfs_fsinfo res;
-	struct statfs tmp;
 
-	error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
+	error = nfs_proc_statvfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
 		&res);
 	if (error) {
-		printk("nfs_statfs: statfs error = %d\n", -error);
+		printk("nfs_statvfs: statfs error = %d\n", -error);
 		res.bsize = res.blocks = res.bfree = res.bavail = 0;
 	}
-	tmp.f_type = NFS_SUPER_MAGIC;
-	tmp.f_bsize = res.bsize;
-	tmp.f_blocks = res.blocks;
-	tmp.f_bfree = res.bfree;
-	tmp.f_bavail = res.bavail;
-	tmp.f_files = 0;
-	tmp.f_ffree = 0;
-	tmp.f_namelen = NAME_MAX;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = NFS_SUPER_MAGIC;
+	buf->f_bsize = res.bsize;
+	buf->f_blocks = res.blocks;
+	buf->f_bfree = res.bfree;
+	buf->f_bavail = res.bavail;
+	buf->f_files = 0;
+	buf->f_ffree = 0;
+	buf->f_namelen = NAME_MAX;
+	return 0;
 }
 
 /*
@@ -680,7 +679,7 @@
 	 */
 	if (attr->ia_valid & ATTR_SIZE) {
 		if (attr->ia_size != fattr.size)
-			printk("nfs_notify_change: attr=%Ld, fattr=%d??\n",
+			printk("nfs_notify_change: attr.size=%Ld, fattr.size=%Ld??\n",
 				attr->ia_size, fattr.size);
 		inode->i_size  = attr->ia_size;
 		inode->i_mtime = fattr.mtime.seconds;
diff -ur linux-23027p1/fs/nfs/proc.c linux-23027p1m1/fs/nfs/proc.c
--- linux-23027p1/fs/nfs/proc.c	Mon Oct 18 21:26:37 1999
+++ linux-23027p1m1/fs/nfs/proc.c	Mon Nov  8 22:58:51 1999
@@ -92,14 +92,14 @@
 
 int
 nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle, int swap,
-			  unsigned long offset, unsigned int count,
+			  loff_t offset, unsigned int count,
 			  void *buffer, struct nfs_fattr *fattr)
 {
 	struct nfs_readargs	arg = { fhandle, offset, count, buffer };
 	struct nfs_readres	res = { fattr, count };
 	int			status;
 
-	dprintk("NFS call  read %d @ %ld\n", count, offset);
+	dprintk("NFS call  read %d @ %Ld\n", count, offset);
 	status = rpc_call(server->client, NFSPROC_READ, &arg, &res,
 			swap? NFS_RPC_SWAPFLAGS : 0);
 	dprintk("NFS reply read: %d\n", status);
@@ -108,13 +108,13 @@
 
 int
 nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle, int swap,
-			unsigned long offset, unsigned int count,
+			loff_t offset, unsigned int count,
 			const void *buffer, struct nfs_fattr *fattr)
 {
 	struct nfs_writeargs	arg = { fhandle, offset, count, buffer };
 	int			status;
 
-	dprintk("NFS call  write %d @ %ld\n", count, offset);
+	dprintk("NFS call  write %d @ %Ld\n", count, offset);
 	status = rpc_call(server->client, NFSPROC_WRITE, &arg, fattr,
 			swap? (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS) : 0);
 	dprintk("NFS reply read: %d\n", status);
@@ -217,7 +217,7 @@
 }
 
 int
-nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
+nfs_proc_statvfs(struct nfs_server *server, struct nfs_fh *fhandle,
 			struct nfs_fsinfo *info)
 {
 	int	status;
diff -ur linux-23027p1/fs/nfs/read.c linux-23027p1m1/fs/nfs/read.c
--- linux-23027p1/fs/nfs/read.c	Sat Oct 30 02:45:32 1999
+++ linux-23027p1m1/fs/nfs/read.c	Mon Nov  8 22:58:51 1999
@@ -52,7 +52,7 @@
  */
 static inline void
 nfs_readreq_setup(struct nfs_rreq *req, struct nfs_fh *fh,
-		  unsigned long offset, void *buffer, unsigned int rsize)
+		  loff_t offset, void *buffer, unsigned int rsize)
 {
 	req->ra_args.fh     = fh;
 	req->ra_args.offset = offset;
@@ -70,10 +70,10 @@
 nfs_readpage_sync(struct dentry *dentry, struct inode *inode, struct page *page)
 {
 	struct nfs_rreq	rqst;
-	unsigned long	offset = page->index << PAGE_CACHE_SHIFT;
+	loff_t		offset = ((loff_t)page->index) << PAGE_CACHE_SHIFT;
 	char		*buffer = (char *) page_address(page);
 	int		rsize = NFS_SERVER(inode)->rsize;
-	int		result, refresh = 0;
+	int		result = 0, refresh = 0;
 	int		count = PAGE_SIZE;
 	int		flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0;
 
@@ -83,11 +83,24 @@
 		if (count < rsize)
 			rsize = count;
 
-		dprintk("NFS: nfs_proc_read(%s, (%s/%s), %ld, %d, %p)\n",
+		dprintk("NFS: nfs_proc_read(%s, (%s/%s), %Ld, %d, %p)\n",
 			NFS_SERVER(inode)->hostname,
 			dentry->d_parent->d_name.name, dentry->d_name.name,
 			offset, rsize, buffer);
 
+		/* FIXME: NFSv3 could allow 64-bit offsets! ... */
+
+		if (offset > 0x7ffffffeULL) {
+		  if (result)
+		  	break;
+		  result = -EOVERFLOW;
+		  goto io_error;
+		}
+		if ((offset + rsize) > 0x7fffffffULL) /* 2G-1 */
+		  rsize = 0x7fffffffULL - offset;
+
+		/* ... END FIXME! */
+
 		/* Set up arguments and perform rpc call */
 		nfs_readreq_setup(&rqst, NFS_FH(dentry), offset, buffer, rsize);
 		lock_kernel();
@@ -166,8 +179,16 @@
 	unsigned long address = page_address(page);
 	struct nfs_rreq	*req;
 	int		result = -1, flags;
+	loff_t loffset	= ((loff_t)page->index) << PAGE_CACHE_SHIFT;
 
 	dprintk("NFS: nfs_readpage_async(%p)\n", page);
+
+	/* FIXME: NFSv3 allows 64-bit offsets.. */
+	if ((loffset + PAGE_SIZE) >= 0x7fffffffULL) {
+	  dprintk("NFS: Async read beyond 2G-1 marker!\n");
+	  return -EOVERFLOW;
+	}
+
 	if (NFS_CONGESTED(inode))
 		goto out_defer;
 
@@ -179,7 +200,7 @@
 
 	/* Initialize request */
 	/* N.B. Will the dentry remain valid for life of request? */
-	nfs_readreq_setup(req, NFS_FH(dentry), page->index << PAGE_CACHE_SHIFT,
+	nfs_readreq_setup(req, NFS_FH(dentry), loffset,
 				(void *) address, PAGE_SIZE);
 	req->ra_inode = inode;
 	req->ra_page = page; /* count has been incremented by caller */
@@ -224,8 +245,8 @@
 	int		error;
 
 	lock_kernel();
-	dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
-		page, PAGE_SIZE, page->index);
+	dprintk("NFS: nfs_readpage (%p %ld@%Lu)\n",
+		page, PAGE_SIZE, ((loff_t)page->index) << PAGE_CACHE_SHIFT);
 	get_page(page);
 
 	/*
diff -ur linux-23027p1/fs/nfs/symlink.c linux-23027p1m1/fs/nfs/symlink.c
--- linux-23027p1/fs/nfs/symlink.c	Tue Oct 26 20:41:06 1999
+++ linux-23027p1m1/fs/nfs/symlink.c	Mon Nov  8 22:58:51 1999
@@ -26,6 +26,7 @@
 
 static int nfs_readlink(struct dentry *, char *, int);
 static struct dentry *nfs_follow_link(struct dentry *, struct dentry *, unsigned int);
+extern long nfs_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -50,7 +51,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	nfs_pathconf,		/* pathconf */
 };
 
 /* Symlink caching in the page cache is even more simplistic
diff -ur linux-23027p1/fs/nfs/write.c linux-23027p1m1/fs/nfs/write.c
--- linux-23027p1/fs/nfs/write.c	Sat Oct 30 02:45:32 1999
+++ linux-23027p1m1/fs/nfs/write.c	Mon Nov  8 22:58:51 1999
@@ -93,21 +93,39 @@
 	int		result, refresh = 0, written = 0;
 	u8		*buffer;
 	struct nfs_fattr fattr;
+	loff_t		loffset = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + offset;
 
 	lock_kernel();
-	dprintk("NFS:      nfs_writepage_sync(%s/%s %d@%lu/%ld)\n",
+	dprintk("NFS:      nfs_writepage_sync(%s/%s %d@%Lu/%ld)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		count, page->index, offset);
+		count, loffset, offset);
 
 	buffer = (u8 *) page_address(page) + offset;
-	offset += page->index << PAGE_CACHE_SHIFT;
+	loffset += offset;
+
+	/* FIXME: NFSv3 !!! */
+#if 1
+	if (loffset >= 0x7ffffffeULL)
+	  return -EFBIG;
+	if ((loffset + count) >= 0x7fffffffULL) {
+	  /* At MOST this much! */
+	  count = 0x7fffffffULL - loffset;
+	}
+#else
+	if (S_ISREG(inode->i_flags) &&
+	    !(dentry->d_file->f_flags & O_LARGEFILE) &&
+	    (!off_t_presentable(loffset) ||
+	     !off_t_presentable(loffset + count))) {
+	  /* Writing beyond LargeFile maximums without O_LARGEFILE */
+	}
+#endif
 
 	do {
 		if (count < wsize && !IS_SWAPFILE(inode))
 			wsize = count;
 
 		result = nfs_proc_write(NFS_DSERVER(dentry), NFS_FH(dentry),
-					IS_SWAPFILE(inode), offset, wsize,
+					IS_SWAPFILE(inode), loffset, wsize,
 					buffer, &fattr);
 
 		if (result < 0) {
@@ -120,15 +138,15 @@
 			wsize, result);
 		refresh = 1;
 		buffer  += wsize;
-		offset  += wsize;
+		loffset += wsize;
 		written += wsize;
 		count   -= wsize;
 		/*
 		 * If we've extended the file, update the inode
 		 * now so we don't invalidate the cache.
 		 */
-		if (offset > inode->i_size)
-			inode->i_size = offset;
+		if (loffset > inode->i_size)
+			inode->i_size = loffset;
 	} while (count);
 
 io_error:
@@ -285,9 +303,9 @@
 	struct nfs_wreq *wreq;
 	struct rpc_task	*task;
 
-	dprintk("NFS:      create_write_request(%s/%s, %ld+%d)\n",
+	dprintk("NFS:      create_write_request(%s/%s, %Ld+%d)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		(page->index << PAGE_CACHE_SHIFT) + offset, bytes);
+		(((loff_t)page->index) << PAGE_CACHE_SHIFT) + offset, bytes);
 
 	/* FIXME: Enforce hard limit on number of concurrent writes? */
 	wreq = kmem_cache_alloc(nfs_wreq_cachep, SLAB_KERNEL);
@@ -433,9 +451,9 @@
 	int		synchronous = file->f_flags & O_SYNC;
 	int		retval;
 
-	dprintk("NFS:      nfs_updatepage(%s/%s %d@%ld)\n",
+	dprintk("NFS:      nfs_updatepage(%s/%s %d@%Ld)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		count, (page->index << PAGE_CACHE_SHIFT) +offset);
+		count, (((loff_t)page->index) << PAGE_CACHE_SHIFT) +offset);
 
 	/*
 	 * Try to find a corresponding request on the writeback queue.
@@ -620,7 +638,7 @@
 	/* Setup the task struct for a writeback call */
 	req->wb_flags |= NFS_WRITE_INPROGRESS;
 	req->wb_args.fh     = NFS_FH(dentry);
-	req->wb_args.offset = (page->index << PAGE_CACHE_SHIFT) + req->wb_offset;
+	req->wb_args.offset = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + req->wb_offset;
 	req->wb_args.count  = req->wb_bytes;
 	req->wb_args.buffer = (void *) (page_address(page) + req->wb_offset);
 
diff -ur linux-23027p1/fs/nfsd/nfs3proc.c linux-23027p1m1/fs/nfsd/nfs3proc.c
--- linux-23027p1/fs/nfsd/nfs3proc.c	Mon Apr 12 20:07:36 1999
+++ linux-23027p1m1/fs/nfsd/nfs3proc.c	Mon Nov  8 22:58:51 1999
@@ -427,16 +427,16 @@
  * Get file system info
  */
 static int
-nfsd3_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle   *argp,
+nfsd3_proc_statvfs(struct svc_rqst * rqstp, struct nfsd_fhandle   *argp,
 					  struct nfsd3_statfsres *resp)
 {
 	int	nfserr;
 
-	dprintk("nfsd: STATFS   %x/%ld\n",
+	dprintk("nfsd: STATVFS   %x/%ld\n",
 				SVCFH_DEV(&argp->fh),
 				SVCFH_INO(&argp->fh));
 
-	nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
+	nfserr = nfsd_statvfs(rqstp, &argp->fh, &resp->stats);
 	fh_put(&argp->fh);
 	RETURN(nfserr);
 }
@@ -479,7 +479,7 @@
   PROC(mkdir,	 createargs,	diropres,	fhandle, RC_REPLBUFF),
   PROC(rmdir,	 diropargs,	void,		void,	 RC_REPLSTAT),
   PROC(readdir,	 readdirargs,	readdirres,	void,	 RC_REPLSTAT),
-  PROC(statfs,	 fhandle,	statfsres,	void,	 RC_NOCACHE),
+  PROC(statvfs,	 fhandle,	statfsres,	void,	 RC_NOCACHE),
 };
 
 
diff -ur linux-23027p1/fs/nfsd/nfs3xdr.c linux-23027p1m1/fs/nfsd/nfs3xdr.c
--- linux-23027p1/fs/nfsd/nfs3xdr.c	Mon Apr  7 21:35:31 1997
+++ linux-23027p1m1/fs/nfsd/nfs3xdr.c	Mon Nov  8 22:58:51 1999
@@ -690,8 +690,8 @@
 nfs3svc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd3_statfsres *resp)
 {
-	struct statfs	*s = &resp->stats;
-	u64		bs = s->f_bsize;
+	struct statvfs64 *s = &resp->stats;
+	u64		  bs = s->f_bsize;
 
 	*p++ = xdr_zero;	/* no post_op_attr */
 
diff -ur linux-23027p1/fs/nfsd/nfsproc.c linux-23027p1m1/fs/nfsd/nfsproc.c
--- linux-23027p1/fs/nfsd/nfsproc.c	Mon Apr 12 20:08:18 1999
+++ linux-23027p1m1/fs/nfsd/nfsproc.c	Mon Nov  8 22:58:51 1999
@@ -471,14 +471,14 @@
  * Get file system info
  */
 static int
-nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle   *argp,
+nfsd_proc_statvfs(struct svc_rqst * rqstp, struct nfsd_fhandle   *argp,
 					  struct nfsd_statfsres *resp)
 {
 	int	nfserr;
 
-	dprintk("nfsd: STATFS   %p\n", SVCFH_DENTRY(&argp->fh));
+	dprintk("nfsd: STATVFS   %p\n", SVCFH_DENTRY(&argp->fh));
 
-	nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
+	nfserr = nfsd_statvfs(rqstp, &argp->fh, &resp->stats);
 	fh_put(&argp->fh);
 	RETURN(nfserr);
 }
@@ -519,7 +519,7 @@
   PROC(mkdir,	 createargs,	diropres,	fhandle,	RC_REPLBUFF),
   PROC(rmdir,	 diropargs,	void,		none,		RC_REPLSTAT),
   PROC(readdir,	 readdirargs,	readdirres,	none,		RC_REPLBUFF),
-  PROC(statfs,	 fhandle,	statfsres,	none,		RC_NOCACHE),
+  PROC(statvfs,	 fhandle,	statfsres,	none,		RC_NOCACHE),
 };
 
 
diff -ur linux-23027p1/fs/nfsd/nfsxdr.c linux-23027p1m1/fs/nfsd/nfsxdr.c
--- linux-23027p1/fs/nfsd/nfsxdr.c	Wed Nov 26 23:08:38 1997
+++ linux-23027p1m1/fs/nfsd/nfsxdr.c	Mon Nov  8 22:58:51 1999
@@ -412,7 +412,7 @@
 nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd_statfsres *resp)
 {
-	struct statfs	*stat = &resp->stats;
+	struct statvfs64	*stat = &resp->stats;
 
 	*p++ = htonl(8 * 1024);		/* max transfer size */
 	*p++ = htonl(stat->f_bsize);
diff -ur linux-23027p1/fs/nfsd/vfs.c linux-23027p1m1/fs/nfsd/vfs.c
--- linux-23027p1/fs/nfsd/vfs.c	Wed Nov  3 07:36:07 1999
+++ linux-23027p1m1/fs/nfsd/vfs.c	Mon Nov  8 22:58:51 1999
@@ -492,8 +492,9 @@
 
 	/* Write back readahead params */
 	if (ra != NULL) {
-		dprintk("nfsd: raparms %ld %ld %ld %ld %ld\n",
-			file.f_reada, file.f_ramax, file.f_raend,
+		dprintk("nfsd: raparms %d %d %Ld %d %d\n",
+			file.f_reada, file.f_ramax,
+			((loff_t)file.f_raend) << PAGE_CACHE_SHIFT,
 			file.f_ralen, file.f_rawin);
 		ra->p_reada = file.f_reada;
 		ra->p_ramax = file.f_ramax;
@@ -1298,12 +1299,11 @@
  * 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_statvfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct statvfs64 *stat)
 {
 	struct dentry		*dentry;
 	struct inode		*inode;
 	struct super_block	*sb;
-	mm_segment_t		oldfs;
 	int			err;
 
 	err = fh_verify(rqstp, fhp, 0, MAY_NOP);
@@ -1313,13 +1313,10 @@
 	inode = dentry->d_inode;
 
 	err = nfserr_io;
-	if (!(sb = inode->i_sb) || !sb->s_op->statfs)
+	if (!(sb = inode->i_sb) || !sb->s_op->statvfs)
 		goto out;
 
-	oldfs = get_fs();
-	set_fs (KERNEL_DS);
-	sb->s_op->statfs(sb, stat, sizeof(*stat));
-	set_fs (oldfs);
+	sb->s_op->statvfs(sb, stat);
 	err = 0;
 
 out:
diff -ur linux-23027p1/fs/ntfs/fs.c linux-23027p1m1/fs/ntfs/fs.c
--- linux-23027p1/fs/ntfs/fs.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/ntfs/fs.c	Mon Nov  8 22:58:51 1999
@@ -28,12 +28,40 @@
 #include <linux/nls.h>
 #include <linux/locks.h>
 #include <linux/init.h>
+#include <linux/unistd.h>
 
 /* Forward declarations */
 static struct inode_operations ntfs_dir_inode_operations;
 
 #define ITEM_SIZE 2040
 
+static long ntfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return 255;
+
+	case _PC_NO_TRUNC:
+		return 0;	/* Non-UNIX semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 /* io functions to user space */
 static void ntfs_putuser(ntfs_io* dest,void *src,ntfs_size_t len)
 {
@@ -447,6 +475,7 @@
 	NULL, /* permission */
 	NULL, /* smap */
 	NULL, /* revalidate */
+	ntfs_pathconf, /* pathconf */
 };
 
 #ifdef CONFIG_NTFS_RW
@@ -630,6 +659,7 @@
 	NULL, /* permission */
 	NULL, /* smap */
 	NULL, /* revalidate */
+	ntfs_pathconf, /* pathconf */
 };
 
 static struct file_operations ntfs_dir_operations = {
@@ -679,6 +709,7 @@
 	NULL, /* permission */
 	NULL, /* smap */
 	NULL, /* revalidate */
+	ntfs_pathconf, /* pathconf */
 };
 
 /* ntfs_read_inode is called by the Virtual File System (the kernel layer that
@@ -813,34 +844,33 @@
 }
 
 /* Called by the kernel when asking for stats */
-static int ntfs_statfs(struct super_block *sb, struct statfs *sf, int bufsize)
+static int ntfs_statvfs(struct super_block *sb, struct statvfs64 *sf)
 {
-	struct statfs fs;
 	struct inode *mft;
 	ntfs_volume *vol;
 	int error;
 
-	ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");
+	ntfs_debug(DEBUG_OTHER, "ntfs_statvfs\n");
 	vol=NTFS_SB2VOL(sb);
-	memset(&fs,0,sizeof(fs));
-	fs.f_type=NTFS_SUPER_MAGIC;
-	fs.f_bsize=vol->clustersize;
+	sf->f_type=NTFS_SUPER_MAGIC;
+	sf->f_bsize=vol->clustersize;
 
-	error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &fs.f_blocks );
+	error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &sf->f_blocks );
 	if( error )
 		return -error;
-	fs.f_bfree=ntfs_get_free_cluster_count(vol->bitmap);
-	fs.f_bavail=fs.f_bfree;
+	sf->f_bfree=ntfs_get_free_cluster_count(vol->bitmap);
+	sf->f_bavail=sf->f_bfree;
 
 	/* Number of files is limited by free space only, so we lie here */
-	fs.f_ffree=0;
+	sf->f_ffree=0;
 	mft=iget(sb,FILE_MFT);
-	fs.f_files=mft->i_size/vol->mft_recordsize;
+	/* So ... we lie... thus this following cast of loff_t value
+	   is ok here.. */
+	sf->f_files = (u_long)mft->i_size / vol->mft_recordsize;
 	iput(mft);
 
 	/* should be read from volume */
-	fs.f_namelen=255;
-	copy_to_user(sf,&fs,bufsize);
+	sf->f_namelen=255;
 	return 0;
 }
 
@@ -865,7 +895,7 @@
 	NULL, /* notify_change */
 	ntfs_put_super,
 	NULL, /* write_super */
-	ntfs_statfs,
+	ntfs_statvfs,
 	ntfs_remount_fs, /* remount */
 	_ntfs_clear_inode, /* clear_inode */ 
 };
diff -ur linux-23027p1/fs/ntfs/super.c linux-23027p1m1/fs/ntfs/super.c
--- linux-23027p1/fs/ntfs/super.c	Mon Apr 12 20:05:58 1999
+++ linux-23027p1m1/fs/ntfs/super.c	Mon Nov  8 22:58:51 1999
@@ -253,7 +253,7 @@
  * Writes the volume size into vol_size. Returns 0 if successful
  * or error.
  */
-int ntfs_get_volumesize(ntfs_volume *vol, long *vol_size )
+int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size )
 {
 	ntfs_io io;
 	ntfs_u64 size;
@@ -274,9 +274,7 @@
 	ntfs_getput_clusters(vol,0,0,&io);
 	size=NTFS_GETU64(cluster0+0x28);
 	ntfs_free(cluster0);
-	/* FIXME: more than 2**32 cluster */
-	/* FIXME: gcc will emit udivdi3 if we don't truncate it */
-	*vol_size = ((unsigned long)size)/vol->clusterfactor;
+	*vol_size = size;
 	return 0;
 }
 
diff -ur linux-23027p1/fs/ntfs/super.h linux-23027p1m1/fs/ntfs/super.h
--- linux-23027p1/fs/ntfs/super.h	Mon Apr 12 20:05:58 1999
+++ linux-23027p1m1/fs/ntfs/super.h	Mon Nov  8 22:58:51 1999
@@ -10,7 +10,7 @@
 #define ALLOC_REQUIRE_SIZE     2
 
 int ntfs_get_free_cluster_count(ntfs_inode *bitmap);
-int ntfs_get_volumesize(ntfs_volume *vol, long *vol_size );
+int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size );
 int ntfs_init_volume(ntfs_volume *vol,char *boot);
 int ntfs_load_special_files(ntfs_volume *vol);
 int ntfs_release_volume(ntfs_volume *vol);
diff -ur linux-23027p1/fs/open.c linux-23027p1m1/fs/open.c
--- linux-23027p1/fs/open.c	Sun Oct 31 19:25:38 1999
+++ linux-23027p1m1/fs/open.c	Mon Nov  8 22:58:51 1999
@@ -9,12 +9,14 @@
 #include <linux/file.h>
 #include <linux/smp_lock.h>
 #include <linux/quotaops.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
 asmlinkage long sys_statfs(const char * path, struct statfs * buf)
 {
 	struct dentry * dentry;
+	struct statvfs64 sbuf64;
 	int error;
 
 	lock_kernel();
@@ -25,10 +27,25 @@
 		struct super_block * sb = inode->i_sb;
 
 		error = -ENODEV;
-		if (sb && sb->s_op && sb->s_op->statfs)
-			error = sb->s_op->statfs(sb, buf, sizeof(struct statfs));
+		if (sb && sb->s_op && sb->s_op->statvfs)
+			error = sb->s_op->statvfs(sb, &sbuf64);
 
 		dput(dentry);
+
+		if (!error) {
+			struct statfs   sbuf;
+			memset(&sbuf,0,sizeof(sbuf));
+			sbuf.f_type    = sbuf64.f_type;
+			sbuf.f_bsize   = sbuf64.f_bsize;
+			sbuf.f_blocks  = sbuf64.f_blocks;
+			sbuf.f_bfree   = sbuf64.f_bfree;
+			sbuf.f_bavail  = sbuf64.f_bavail;
+			sbuf.f_files   = sbuf64.f_files;
+			sbuf.f_ffree   = sbuf64.f_ffree;
+			sbuf.f_fsid    = sbuf64.f_fsid;
+			sbuf.f_namelen = sbuf64.f_namelen;
+			error = copy_to_user(buf, &sbuf, sizeof(*buf));
+		}
 	}
 	unlock_kernel();
 	return error;
@@ -38,6 +55,7 @@
 {
 	struct file * file;
 	struct super_block * sb;
+	struct statvfs64 sbuf64;
 	int error;
 
 	error = -EBADF;
@@ -47,24 +65,113 @@
 	error = -ENODEV;
 	sb = file->f_dentry->d_inode->i_sb;
 	lock_kernel();
-	if (sb && sb->s_op && sb->s_op->statfs)
-		error = sb->s_op->statfs(sb, buf, sizeof(struct statfs));
+	if (sb && sb->s_op && sb->s_op->statvfs)
+		error = sb->s_op->statvfs(sb, &sbuf64);
+	if (!error) {
+		struct statfs   sbuf;
+		memset(&sbuf,0,sizeof(sbuf));
+		sbuf.f_type    = sbuf64.f_type;
+		sbuf.f_bsize   = sbuf64.f_bsize;
+		sbuf.f_blocks  = sbuf64.f_blocks;
+		sbuf.f_bfree   = sbuf64.f_bfree;
+		sbuf.f_bavail  = sbuf64.f_bavail;
+		sbuf.f_files   = sbuf64.f_files;
+		sbuf.f_ffree   = sbuf64.f_ffree;
+		sbuf.f_fsid    = sbuf64.f_fsid;
+		sbuf.f_namelen = sbuf64.f_namelen;
+		error = copy_to_user(buf, &sbuf, sizeof(*buf));
+	}
 	unlock_kernel();
 	fput(file);
 out:
 	return error;
 }
 
-int do_truncate(struct dentry *dentry, unsigned long length)
+asmlinkage long sys_statvfs64(const char * path, struct statvfs64 * buf)
+{
+	struct dentry * dentry;
+	int error;
+	struct statvfs64 sbuf64;
+
+	lock_kernel();
+	dentry = namei(path);
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		struct inode * inode = dentry->d_inode;
+
+		error = -ENOSYS;
+		if (inode->i_sb->s_op->statvfs)
+			error = inode->i_sb->s_op->statvfs(inode->i_sb, &sbuf64);
+		dput(dentry);
+		if (!error)
+			error = copy_to_user(buf, &sbuf64, sizeof(*buf));
+	}
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage long sys_fstatvfs64(unsigned int fd, struct statvfs64 * buf)
+{
+	struct file * file;
+	struct inode * inode;
+	struct dentry * dentry;
+	struct super_block * sb;
+	struct statvfs64 sbuf64;
+	int error;
+
+	lock_kernel();
+	error = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto out;
+	error = -ENOENT;
+	if (!(dentry = file->f_dentry))
+		goto out_putf;
+	if (!(inode = dentry->d_inode))
+		goto out_putf;
+	error = -ENODEV;
+	if (!(sb = inode->i_sb))
+		goto out_putf;
+	error = -ENOSYS;
+	if (sb->s_op->statvfs)
+		error = sb->s_op->statvfs(sb, &sbuf64);
+	if (!error)
+		error = copy_to_user(buf, &sbuf64, sizeof(*buf));
+
+out_putf:
+	fput(file);
+out:
+	unlock_kernel();
+	return error;
+}
+
+long do_truncate(struct dentry *dentry, loff_t length)
 {
 	struct inode *inode = dentry->d_inode;
 	int error;
 	struct iattr newattrs;
 
-	/* Not pretty: "inode->i_size" shouldn't really be "off_t". But it is. */
-	if ((off_t) length < 0)
+	if (length < 0)
 		return -EINVAL;
 
+	if (inode->i_op->pathconf &&
+	    inode->i_op->pathconf(inode,_PC_FILESIZEBITS) <= 32) {
+	  if (length > 0x7fffffffULL) {
+	    /* Target filesystem doesn't support Large Files;
+	       now we presume this means *only* 2G, although some
+	       may have up to 4G ... */
+	    return -EFBIG;
+	  }
+	}
+
+	if (current->rlimfsz.rlim_cur < inode->i_size) {
+		/* If the target size is higher than our current (soft)
+		   file size limit, a SIGXFSZ shall be sent along
+		   with error -EFBIG. */
+		send_sig(SIGXFSZ, current, 0);
+		return -EFBIG;
+	}
+
 	down(&inode->i_sem);
 	newattrs.ia_size = length;
 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
@@ -79,11 +186,12 @@
 	return error;
 }
 
-asmlinkage long sys_truncate(const char * path, unsigned long length)
+asmlinkage long sys_truncate(const char * path, unsigned long slength)
 {
 	struct dentry * dentry;
 	struct inode * inode;
 	int error;
+	loff_t length = slength;
 
 	lock_kernel();
 	dentry = namei(path);
@@ -93,7 +201,7 @@
 		goto out;
 	inode = dentry->d_inode;
 
-	error = -EACCES;
+	error = -EISDIR;
 	if (S_ISDIR(inode->i_mode))
 		goto dput_and_out;
 
@@ -109,6 +217,10 @@
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto dput_and_out;
 
+	error = -EINVAL;	/* New length may not exceed current size */
+	if (inode->i_size < length)
+		goto dput_and_out;
+
 	error = get_write_access(inode);
 	if (error)
 		goto dput_and_out;
@@ -144,12 +256,120 @@
 		goto out_putf;
 	if (!(inode = dentry->d_inode))
 		goto out_putf;
+	error = -EISDIR;
+	if (S_ISDIR(inode->i_mode))
+		goto out_putf;
+	error = -EACCES;
+	if (!(file->f_mode & FMODE_WRITE))
+		goto out_putf;
+	error = -EPERM;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		goto out_putf;
+	error = -EINVAL;
+	if (inode->i_size < length)
+		goto out_putf;
+	/* Large File Summit */
+	error = -EFBIG;
+	if (S_ISREG(inode->i_mode) && !(file->f_flags & O_LARGEFILE) &&
+	    !off_t_presentable(inode->i_size))
+		goto out_putf;
+	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
+				  length<inode->i_size ? length : inode->i_size,
+				  abs(inode->i_size - length));
+	if (!error)
+		error = do_truncate(dentry, length);
+out_putf:
+	fput(file);
+out:
+	unlock_kernel();
+	return error;
+}
+
+#if BITS_PER_LONG < 64
+asmlinkage long sys_truncate64(const char * path, loff_t length)
+{
+	struct dentry * dentry;
+	struct inode * inode;
+	int error;
+
+	lock_kernel();
+	dentry = namei(path);
+
+	error = PTR_ERR(dentry);
+	if (IS_ERR(dentry))
+		goto out;
+	inode = dentry->d_inode;
+
+	error = -EACCES;
+	if (S_ISDIR(inode->i_mode))
+		goto dput_and_out;
+
+	error = permission(inode,MAY_WRITE);
+	if (error)
+		goto dput_and_out;
+
+	error = -EROFS;
+	if (IS_RDONLY(inode))
+		goto dput_and_out;
+
+	error = -EPERM;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		goto dput_and_out;
+
+	error = -EFBIG;
+	if (inode->i_size < length)
+		goto dput_and_out;
+
+	error = get_write_access(inode);
+	if (error)
+		goto dput_and_out;
+
+	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL,
+				  length < inode->i_size ? length : inode->i_size,
+				  abs(inode->i_size - length));
+	if (!error) {
+		DQUOT_INIT(inode);
+		error = do_truncate(dentry, length);
+	}
+	put_write_access(inode);
+dput_and_out:
+	dput(dentry);
+out:
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
+{
+	struct inode * inode;
+	struct dentry *dentry;
+	struct file * file;
+	int error;
+
+	lock_kernel();
+	error = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto out;
+	error = -ENOENT;
+	if (!(dentry = file->f_dentry))
+		goto out_putf;
+	if (!(inode = dentry->d_inode))
+		goto out_putf;
 	error = -EACCES;
 	if (S_ISDIR(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
 		goto out_putf;
 	error = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto out_putf;
+	error = -EINVAL;
+	if (inode->i_size < length || length < 0)
+		goto out_putf;
+	/* Large File Summit */
+	error = -EFBIG;
+	if (S_ISREG(inode->i_mode) && !(file->f_flags & O_LARGEFILE) &&
+	    !off_t_presentable(inode->i_size))
+		goto out_putf;
 	error = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
 				  length<inode->i_size ? length : inode->i_size,
 				  abs(inode->i_size - length));
@@ -162,6 +382,7 @@
 out:
 	return error;
 }
+#endif /* BITS_PER_LONG < 64 */
 
 #if !(defined(__alpha__) || defined(__ia64__))
 
@@ -653,6 +874,16 @@
 			goto cleanup_dentry;
 	}
 
+	/* L-F-S spec: 3.1.1.3:  If open() is done without  O_LARGEFILE,
+	   and the target (regular) file size exceeds that presentable with
+	   'off_t' datatype in the system, the open shall be rejected with
+	   EOVERFLOW  error. */
+	if (S_ISREG(inode->i_mode) && !(flags & O_LARGEFILE) &&
+	    !off_t_presentable(inode->i_size)) {
+		error = -EOVERFLOW;
+		goto cleanup_all;
+	}
+
 	f->f_dentry = dentry;
 	f->f_pos = 0;
 	f->f_reada = 0;
@@ -786,8 +1017,7 @@
 #ifndef __alpha__
 
 /*
- * For backward compatibility?  Maybe this should be moved
- * into arch/i386 instead?
+ * This one is used at about all platforms, except Alpha..
  */
 asmlinkage long sys_creat(const char * pathname, int mode)
 {
@@ -827,7 +1057,7 @@
  * or not in the open-files bitmap.  dup2 uses this to retain the fd
  * without races.
  */
-int do_close(unsigned int fd, int release)
+long do_close(unsigned int fd, int release)
 {
 	int error;
 	struct file * filp;
diff -ur linux-23027p1/fs/partitions/acorn.c linux-23027p1m1/fs/partitions/acorn.c
--- linux-23027p1/fs/partitions/acorn.c	Thu Sep 30 00:02:59 1999
+++ linux-23027p1m1/fs/partitions/acorn.c	Mon Nov  8 22:58:51 1999
@@ -16,6 +16,8 @@
 
 #include "acorn.h"
 
+extern unsigned int get_ptable_blocksize(kdev_t);
+
 extern void add_gd_partition(struct gendisk *hd, unsigned int minor, unsigned int start, unsigned int size);
 
 static void
diff -ur linux-23027p1/fs/pipe.c linux-23027p1m1/fs/pipe.c
--- linux-23027p1/fs/pipe.c	Wed Sep  8 21:20:20 1999
+++ linux-23027p1m1/fs/pipe.c	Mon Nov  8 22:58:51 1999
@@ -9,6 +9,7 @@
 #include <linux/poll.h>
 #include <linux/malloc.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -529,9 +530,10 @@
 	NULL
 };
 
+static struct inode_operations pipe_inode_operations;
+
 static struct inode * get_pipe_inode(void)
 {
-	extern struct inode_operations pipe_inode_operations;
 	struct inode *inode = get_empty_inode();
 	unsigned long page;
 
@@ -575,7 +577,14 @@
 	return NULL;
 }
 
-struct inode_operations pipe_inode_operations = {
+long pipe_pathconf(struct inode *inode, long option)
+{
+	if (option == _PC_PIPE_BUF)
+		return PIPE_BUF;
+	return -EINVAL;
+}
+
+static struct inode_operations pipe_inode_operations = {
 	&rdwr_pipe_fops,
 	NULL,			/* create */
 	NULL,			/* lookup */
@@ -595,7 +604,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	pipe_pathconf,		/* pathconf */
 };
 
 int do_pipe(int *fd)
diff -ur linux-23027p1/fs/proc/array.c linux-23027p1m1/fs/proc/array.c
--- linux-23027p1/fs/proc/array.c	Mon Nov  8 22:57:35 1999
+++ linux-23027p1m1/fs/proc/array.c	Mon Nov  8 22:58:51 1999
@@ -498,11 +498,11 @@
  *         + (index into the line)
  */
 /* for systems with sizeof(void*) == 4: */
-#define MAPS_LINE_FORMAT4	  "%08lx-%08lx %s %08lx %s %lu"
-#define MAPS_LINE_MAX4	49 /* sum of 8  1  8  1 4 1 8 1 5 1 10 1 */
+#define MAPS_LINE_FORMAT4	  "%08lx-%08lx %s %16Lx %s %lu"
+#define MAPS_LINE_MAX4	57 /* sum of 8  1  8  1 4 1 16 1 5 1 10 1 */
 
 /* for systems with sizeof(void*) == 8: */
-#define MAPS_LINE_FORMAT8	  "%016lx-%016lx %s %016lx %s %lu"
+#define MAPS_LINE_FORMAT8	  "%016lx-%016lx %s %016Lx %s %lu"
 #define MAPS_LINE_MAX8	73 /* sum of 16  1  16  1 4 1 16 1 5 1 10 1 */
 
 #define MAPS_LINE_MAX	MAPS_LINE_MAX8
@@ -580,7 +580,7 @@
 
 		len = sprintf(line,
 			      sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8,
-			      map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
+			      map->vm_start, map->vm_end, str, ((loff_t)(long)map->vm_pgoff) << PAGE_SHIFT,
 			      kdevname(dev), ino);
 
 		if(map->vm_file) {
diff -ur linux-23027p1/fs/proc/inode.c linux-23027p1m1/fs/proc/inode.c
--- linux-23027p1/fs/proc/inode.c	Mon Nov  8 22:57:35 1999
+++ linux-23027p1m1/fs/proc/inode.c	Mon Nov  8 22:58:51 1999
@@ -107,7 +107,7 @@
 	NULL,
 	proc_put_super,
 	NULL,
-	proc_statfs,
+	proc_statvfs,
 	NULL
 };
 
@@ -236,19 +236,17 @@
 	return NULL;
 }
 
-int proc_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+int proc_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	tmp.f_type = PROC_SUPER_MAGIC;
-	tmp.f_bsize = PAGE_SIZE/sizeof(long);
-	tmp.f_blocks = 0;
-	tmp.f_bfree = 0;
-	tmp.f_bavail = 0;
-	tmp.f_files = 0;
-	tmp.f_ffree = 0;
-	tmp.f_namelen = NAME_MAX;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = PROC_SUPER_MAGIC;
+	buf->f_bsize = PAGE_SIZE/sizeof(long);
+	buf->f_blocks = 0;
+	buf->f_bfree = 0;
+	buf->f_bavail = 0;
+	buf->f_files = 0;
+	buf->f_ffree = 0;
+	buf->f_namelen = NAME_MAX;
+	return 0;
 }
 
 void proc_read_inode(struct inode * inode)
diff -ur linux-23027p1/fs/qnx4/dir.c linux-23027p1m1/fs/qnx4/dir.c
--- linux-23027p1/fs/qnx4/dir.c	Tue Jul  6 05:59:55 1999
+++ linux-23027p1m1/fs/qnx4/dir.c	Mon Nov  8 22:58:51 1999
@@ -20,6 +20,8 @@
 
 #include <asm/segment.h>
 
+extern long qnx4_pathconf(struct inode *, long);
+
 static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir);
 
 static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
@@ -126,5 +128,6 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	qnx4_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/qnx4/file.c linux-23027p1m1/fs/qnx4/file.c
--- linux-23027p1/fs/qnx4/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/qnx4/file.c	Mon Nov  8 22:58:51 1999
@@ -25,6 +25,7 @@
 #include <linux/locks.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
+#include <linux/unistd.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -144,8 +145,34 @@
 }
 #endif
 
+long qnx4_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return QNX4_NAME_MAX;
+	case _PC_NO_TRUNC:
+	  return 0;		/* silent truncation */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 /*
- * We have moostly NULL's here: the current defaults are ok for
+ * We have mostly NULL's here: the current defaults are ok for
  * the qnx4 filesystem.
  */
 static struct file_operations qnx4_file_operations =
@@ -200,7 +227,8 @@
 #endif
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	qnx4_pathconf,		/* pathconf */
 };
 
 static int qnx4_readpage(struct file *file, struct page *page)
@@ -209,13 +237,13 @@
 	struct inode *inode = dentry->d_inode;
 	struct qnx4_inode_info *qnx4_ino = &inode->u.qnx4_i;
 	unsigned long buf;
-	unsigned long offset, avail, readlen;
+	unsigned long offset, avail, readlen; // 4G max size!
 	unsigned long start;
 	unsigned long count;
 	struct buffer_head *bh;
 	int res = -EIO;
 
-	QNX4DEBUG(("qnx4: readpage offset=[%ld]\n", (long) page->offset));
+	QNX4DEBUG(("qnx4: readpage offset=[%Ld]\n", page->index << PAGE_CACHE_SHIFT));
 
 	if (qnx4_ino->i_xblk != 0) {
 		printk("qnx4: sorry, this file is extended, don't know how to handle it (yet) !\n");
@@ -226,7 +254,7 @@
 	buf = page_address(page);
 	clear_bit(PG_uptodate, &page->flags);
 	clear_bit(PG_error, &page->flags);
-	offset = page->offset;
+	offset = page->index << PAGE_CACHE_SHIFT; // 4G limit
 
 	if (offset < inode->i_size) {
 		res = 0;
diff -ur linux-23027p1/fs/qnx4/inode.c linux-23027p1m1/fs/qnx4/inode.c
--- linux-23027p1/fs/qnx4/inode.c	Sat Oct  2 17:49:29 1999
+++ linux-23027p1m1/fs/qnx4/inode.c	Mon Nov  8 22:58:51 1999
@@ -124,7 +124,7 @@
 static void qnx4_put_super(struct super_block *sb);
 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 *, int);
+static int qnx4_statvfs(struct super_block *, struct statvfs64 *);
 
 static struct super_operations qnx4_sops =
 {
@@ -149,7 +149,7 @@
 #else
 	NULL,
 #endif
-	qnx4_statfs,
+	qnx4_statvfs,
 	qnx4_remount,
 	NULL			/* clear_inode */
 };
@@ -225,22 +225,18 @@
 	return NULL;
 }
 
-static int qnx4_statfs(struct super_block *sb,
-		       struct statfs *buf, int bufsize)
+static int qnx4_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
+	buf->f_type = sb->s_magic;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = le32_to_cpu(sb->u.qnx4_sb.BitMap->di_size) * 8;
+	buf->f_bfree = qnx4_count_free_blocks(sb);
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = 0x00;	/* change this !!! */
+	buf->f_ffree = qnx4_count_free_inodes(sb);
+	buf->f_namelen = QNX4_NAME_MAX;
 
-	memset(&tmp, 0, sizeof tmp);
-	tmp.f_type = sb->s_magic;
-	tmp.f_bsize = sb->s_blocksize;
-	tmp.f_blocks = le32_to_cpu(sb->u.qnx4_sb.BitMap->di_size) * 8;
-	tmp.f_bfree = qnx4_count_free_blocks(sb);
-	tmp.f_bavail = tmp.f_bfree;
-	tmp.f_files = 0x00;	/* change this !!! */
-	tmp.f_ffree = qnx4_count_free_inodes(sb);
-	tmp.f_namelen = QNX4_NAME_MAX;
-
-	return copy_to_user(buf, &tmp, bufsize) ? -EFAULT : 0;
+	return 0;
 }
 
 /*
diff -ur linux-23027p1/fs/qnx4/symlinks.c linux-23027p1m1/fs/qnx4/symlinks.c
--- linux-23027p1/fs/qnx4/symlinks.c	Tue Jul  6 05:59:55 1999
+++ linux-23027p1m1/fs/qnx4/symlinks.c	Mon Nov  8 22:58:51 1999
@@ -25,6 +25,7 @@
 
 static int qnx4_readlink(struct dentry *, char *, int);
 static struct dentry *qnx4_follow_link(struct dentry *, struct dentry *, unsigned int follow);
+extern long qnx4_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -50,7 +51,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	qnx4_pathconf,		/* pathconf */
 };
 
 static struct dentry *qnx4_follow_link(struct dentry *dentry,
diff -ur linux-23027p1/fs/read_write.c linux-23027p1m1/fs/read_write.c
--- linux-23027p1/fs/read_write.c	Fri Nov  5 19:57:30 1999
+++ linux-23027p1m1/fs/read_write.c	Mon Nov  8 22:58:51 1999
@@ -39,6 +39,11 @@
 static inline loff_t llseek(struct file *file, loff_t offset, int origin)
 {
 	loff_t (*fn)(struct file *, loff_t, int);
+	umode_t mode = file->f_dentry->d_inode->i_mode;
+
+	/* SUS: Seek done at pipe/fifo/socket must yield ESPIPE .. */
+	if (S_ISFIFO(mode) || S_ISSOCK(mode))
+	  return -ESPIPE;
 
 	fn = default_llseek;
 	if (file->f_op && file->f_op->llseek)
@@ -49,6 +54,7 @@
 asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
 {
 	off_t retval;
+	loff_t oldpos;
 	struct file * file;
 	struct dentry * dentry;
 	struct inode * inode;
@@ -62,13 +68,25 @@
 	if (!(dentry = file->f_dentry) ||
 	    !(inode = dentry->d_inode))
 		goto out_putf;
+
+	oldpos = file->f_pos;
 	retval = -EINVAL;
 	if (origin <= 2) {
-		loff_t res = llseek(file, offset, origin);
+		loff_t res = llseek(file, (loff_t)offset, origin);
 		retval = res;
-		if (res != (loff_t)retval)
-			retval = -EOVERFLOW;	/* LFS: should only happen on 32 bit platforms */
+
+		/* Demand L-F-S compliance only from normal files,
+		   thus raw devices can do whatever they please.. */
+		if (res >= 0 && S_ISREG(inode->i_mode) &&
+		    !(file->f_flags & O_LARGEFILE) &&
+		    !off_t_presentable(file->f_pos+1LL)) {
+			printk("sys_lseek(.., %ld, %d) (oldpos=%Ld) -> %Ld - EOVERFLOW!\n",
+			       offset, origin, oldpos, file->f_pos);
+			file->f_pos = oldpos;
+			retval = -EOVERFLOW;
+		}
 	}
+
 out_putf:
 	fput(file);
 bad:
@@ -85,7 +103,7 @@
 	struct file * file;
 	struct dentry * dentry;
 	struct inode * inode;
-	loff_t offset;
+	loff_t offset, oldpos;
 
 	lock_kernel();
 	retval = -EBADF;
@@ -100,6 +118,7 @@
 	if (origin > 2)
 		goto out_putf;
 
+	oldpos = file->f_pos;
 	offset = llseek(file, ((loff_t) offset_high << 32) | offset_low,
 			origin);
 
@@ -109,6 +128,18 @@
 		if (!copy_to_user(result, &offset, sizeof(offset)))
 			retval = 0;
 	}
+
+#if 0 /* With *THIS* call the resulting offset *IS* presentable */
+	if (!(file->f_flags & O_LARGEFILE) && S_ISREG(inode->i_mode) &&
+	    !off_t_presentable(file->f_pos+1LL)) {
+		/* The target position isn't presentable without
+		   O_LARGEFILE flag being set --> yield error, and
+		   restore the file position. */
+		file->f_pos = oldpos;
+		retval = -EOVERFLOW;
+	}
+#endif
+
 out_putf:
 	fput(file);
 bad:
@@ -311,6 +342,7 @@
 	ssize_t ret;
 	struct file * file;
 	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+	struct inode * inode;
 
 	lock_kernel();
 
@@ -318,10 +350,30 @@
 	file = fget(fd);
 	if (!file)
 		goto bad_file;
+
+	inode = file->f_dentry->d_inode;
+
 	if (!(file->f_mode & FMODE_READ))
 		goto out;
-	ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
-				file, pos, count);
+
+	/* Start position must be non-negative! */
+	if (pos < 0) {
+	  ret = -EINVAL;
+	  goto out;
+	}
+	/* Read starting from beyond the end of file ? */
+	if (inode->i_size <= pos) {
+	  ret = -EOVERFLOW;
+	  goto out;
+	}
+
+	if (!(file->f_flags & O_LARGEFILE) && S_ISREG(inode->i_mode) &&
+	    !off_t_presentable(pos+1LL)) {
+	  ret = -EOVERFLOW;
+	  goto out;
+	}
+
+	ret = locks_verify_area(FLOCK_VERIFY_READ, inode, file, pos, count);
 	if (ret)
 		goto out;
 	ret = -EINVAL;
@@ -343,6 +395,7 @@
 	ssize_t ret;
 	struct file * file;
 	ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
+	struct inode * inode;
 
 	lock_kernel();
 
@@ -352,8 +405,21 @@
 		goto bad_file;
 	if (!(file->f_mode & FMODE_WRITE))
 		goto out;
-	ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode,
-				file, pos, count);
+	/* Start position must be non-negative! */
+	if (pos < 0) {
+	  ret = -EINVAL;
+	  goto out;
+	}
+
+	inode = file->f_dentry->d_inode;
+
+	if (!(file->f_flags & O_LARGEFILE) && S_ISREG(inode->i_mode) &&
+	    !off_t_presentable(pos+1LL)) {
+	  ret = -EOVERFLOW;
+	  goto out;
+	}
+
+	ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, pos, count);
 	if (ret)
 		goto out;
 	ret = -EINVAL;
diff -ur linux-23027p1/fs/readdir.c linux-23027p1m1/fs/readdir.c
--- linux-23027p1/fs/readdir.c	Mon Aug 23 21:15:53 1999
+++ linux-23027p1m1/fs/readdir.c	Mon Nov  8 22:58:51 1999
@@ -196,3 +196,105 @@
 	unlock_kernel();
 	return error;
 }
+
+/*
+ * New, even-more-improved getdents64() (for LFS) interface. 
+ */
+struct linux_dirent64 {
+	__u64		d_ino;		/* 64 bits *should* be enough */
+	__u32		d_off;		/* position within directory */
+	__u32		d_flags;	/* what is stored in  d_data[] */
+	__u32		d_data[8];	/* for future extensions */
+	__u16		d_reclen;
+	char		d_name[1];	/* We must not include limits.h! */
+};
+
+struct getdents_callback64 {
+	struct linux_dirent64 * current_dir;
+	struct linux_dirent64 * previous;
+	int count;
+	int error;
+	int ctrlflags;
+};
+
+static long filldir64(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+{
+	struct linux_dirent64 * dirent;
+	struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
+	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+	__u64 ino64;
+
+	buf->error = -EINVAL;	/* only used if we fail.. */
+	if (reclen > buf->count)
+		return -EINVAL;
+	dirent = buf->previous;
+	if (dirent)
+		put_user(offset, &dirent->d_off);
+	dirent = buf->current_dir;
+	buf->previous = dirent;
+	ino64 = ino;
+	copy_to_user(&dirent->d_reclen, &ino64, sizeof(ino64));
+	copy_to_user(dirent->d_name, name, namlen);
+	put_user(0, dirent->d_name + namlen);
+	((char *) dirent) += reclen;
+	buf->current_dir = dirent;
+	buf->count -= reclen;
+	return 0;
+}
+
+asmlinkage long sys_getdents64(unsigned int fd, void * dirent, unsigned int count, long flags)
+{
+	struct file * file;
+	struct dentry * dentry;
+	struct inode * inode;
+	struct linux_dirent64 * lastdirent;
+	struct getdents_callback64 buf;
+	int error;
+
+	if (flags) return -EINVAL; /* until flags defined.. */
+
+	lock_kernel();
+	error = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto out;
+
+	dentry = file->f_dentry;
+	if (!dentry)
+		goto out_putf;
+
+	inode = dentry->d_inode;
+	if (!inode)
+		goto out_putf;
+
+	buf.current_dir = (struct linux_dirent64 *) dirent;
+	buf.previous = NULL;
+	buf.count = count;
+	buf.error = 0;
+
+	error = -ENOTDIR;
+	if (!file->f_op || !file->f_op->readdir)
+		goto out_putf;
+
+	/*
+	 * Get the inode's semaphore to prevent changes
+	 * to the directory while we read it.
+	 */
+	down(&inode->i_sem);
+	error = file->f_op->readdir(file, &buf, filldir64);
+	up(&inode->i_sem);
+	if (error < 0)
+		goto out_putf;
+	error = buf.error;
+	lastdirent = buf.previous;
+	if (lastdirent) {
+		put_user(file->f_pos, &lastdirent->d_off);
+		error = count - buf.count;
+	}
+
+out_putf:
+	fput(file);
+out:
+	unlock_kernel();
+	return error;
+}
diff -ur linux-23027p1/fs/romfs/inode.c linux-23027p1m1/fs/romfs/inode.c
--- linux-23027p1/fs/romfs/inode.c	Wed Oct 27 01:03:19 1999
+++ linux-23027p1m1/fs/romfs/inode.c	Mon Nov  8 22:58:51 1999
@@ -58,6 +58,7 @@
 #include <linux/locks.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -166,16 +167,13 @@
 /* That's simple too. */
 
 static int
-romfs_statfs(struct super_block *sb, struct statfs *buf, int bufsize)
+romfs_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.f_type = ROMFS_MAGIC;
-	tmp.f_bsize = ROMBSIZE;
-	tmp.f_blocks = (sb->u.romfs_sb.s_maxsize+ROMBSIZE-1)>>ROMBSBITS;
-	tmp.f_namelen = ROMFS_MAXFN;
-	return copy_to_user(buf, &tmp, bufsize) ? -EFAULT : 0;
+	buf->f_type = ROMFS_MAGIC;
+	buf->f_bsize = ROMBSIZE;
+	buf->f_blocks = (sb->u.romfs_sb.s_maxsize+ROMBSIZE-1)>>ROMBSBITS;
+	buf->f_namelen = ROMFS_MAXFN;
+	return 0;
 }
 
 /* some helper routines */
@@ -404,7 +402,7 @@
 	get_page(page);
 	buf = page_address(page);
 
-	offset = page->offset;
+	offset = (page->index) << PAGE_CACHE_SHIFT;
 	if (offset < inode->i_size) {
 		avail = inode->i_size-offset;
 		readlen = min(avail, PAGE_SIZE);
@@ -486,6 +484,32 @@
 	return dentry;
 }
 
+static long romfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		break;	/* This is read-only filesystem! */
+	case _PC_NO_TRUNC:
+		break;	/* This is read-only filesystem! */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		break;	/* This is read-only filesystem! */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 /* Mapping from our types to the kernel */
 
 static struct file_operations romfs_file_operations = {
@@ -525,7 +549,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	romfs_pathconf,		/* pathconf */
 };
 
 static struct file_operations romfs_dir_operations = {
@@ -542,7 +567,7 @@
 	NULL,			/* fsync */
 	NULL,			/* fasync */
 	NULL,			/* check_media_change */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
 };
 
 /* Merged dir/symlink op table.  readdir/lookup/readlink/follow_link
@@ -569,7 +594,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	romfs_pathconf,		/* pathconf */
 };
 
 static struct inode_operations romfs_link_inode_operations = {
@@ -592,7 +618,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	romfs_pathconf,		/* pathconf */
 };
 
 static mode_t romfs_modemap[] =
@@ -678,7 +705,7 @@
 	NULL,			/* notify change */
 	romfs_put_super,	/* put super */
 	NULL,			/* write super */
-	romfs_statfs,		/* statfs */
+	romfs_statvfs,		/* statvfs */
 	NULL			/* remount */
 };
 
diff -ur linux-23027p1/fs/smbfs/cache.c linux-23027p1m1/fs/smbfs/cache.c
--- linux-23027p1/fs/smbfs/cache.c	Thu Oct 28 20:53:51 1999
+++ linux-23027p1m1/fs/smbfs/cache.c	Mon Nov  8 22:58:51 1999
@@ -44,15 +44,15 @@
  * smb-cache code assumes we return a locked page.
  */
 static unsigned long
-get_cached_page(struct address_space *mapping, unsigned long offset, int new)
+get_cached_page(struct address_space *mapping, unsigned long index, int new)
 {
 	struct page * page;
 	struct page ** hash;
 	struct page *cached_page = NULL;
 
  again:
-	hash = page_hash(mapping, offset);
-	page = __find_lock_page(mapping, offset, hash);
+	hash = page_hash(mapping, index);
+	page = __find_lock_page(mapping, index, hash);
 	if(!page && new) {
 		/* not in cache, alloc a new page if we didn't do it yet */
 		if (!cached_page) {
@@ -67,7 +67,7 @@
 		if (page->buffers)
 			BUG();
 		printk(KERN_DEBUG "smbfs: get_cached_page\n");
-		if (add_to_page_cache_unique(page, mapping, offset, hash))
+		if (add_to_page_cache_unique(page, mapping, index, hash))
 			/* Hmm, a page has materialized in the
                            cache. Fine. Go back and get that page
                           instead... */
@@ -92,7 +92,7 @@
 
 /*
  * Get a pointer to the cache_head structure,
- * mapped as the page at offset 0. The page is
+ * mapped as the page at index 0. The page is
  * kept locked while we're using the cache.
  */
 struct cache_head *
@@ -112,7 +112,6 @@
 	{
 		struct cache_index * index = cachep->index;
 		struct cache_block * block;
-		unsigned long offset;
 		int i;
 
 		cachep->valid = 0;
@@ -126,9 +125,8 @@
 printk("smb_get_dircache: cache %s/%s has existing block!\n",
 dentry->d_parent->d_name.name, dentry->d_name.name);
 #endif
-			offset = PAGE_SIZE + (i << PAGE_SHIFT);
 			block = (struct cache_block *) get_cached_page(mapping,
-								offset, 0);
+								i+1, 0);
 			if (!block)
 				goto out;
 			index->block = block;
diff -ur linux-23027p1/fs/smbfs/dir.c linux-23027p1m1/fs/smbfs/dir.c
--- linux-23027p1/fs/smbfs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/smbfs/dir.c	Mon Nov  8 22:58:52 1999
@@ -29,6 +29,8 @@
 static int smb_unlink(struct inode *, struct dentry *);
 static int smb_rename(struct inode *, struct dentry *,
 		      struct inode *, struct dentry *);
+extern long smb_pathconf(struct inode *, long);
+
 
 static struct file_operations smb_dir_operations =
 {
@@ -67,6 +69,7 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	smb_revalidate_inode,	/* revalidate */
+	smb_pathconf,		/* pathconf */
 };
 
 static ssize_t
diff -ur linux-23027p1/fs/smbfs/file.c linux-23027p1m1/fs/smbfs/file.c
--- linux-23027p1/fs/smbfs/file.c	Sat Oct 30 02:45:32 1999
+++ linux-23027p1m1/fs/smbfs/file.c	Mon Nov  8 22:58:52 1999
@@ -15,6 +15,7 @@
 #include <linux/malloc.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -120,25 +121,42 @@
  * Offset is the data offset within the page.
  */
 static int
-smb_writepage_sync(struct dentry *dentry, struct page *page,
+smb_writepage_sync(struct file *file, struct page *page,
 		   unsigned long offset, unsigned int count)
 {
+	struct dentry * dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	u8 *buffer = (u8 *) page_address(page) + offset;
 	int wsize = smb_get_wsize(server_from_dentry(dentry));
 	int result, written = 0;
 
-	offset += page->index << PAGE_CACHE_SHIFT;
+	loff_t loffset = offset + (((loff_t)page->index) << PAGE_CACHE_SHIFT);
+
 #ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_writepage_sync: file %s/%s, count=%d@%ld, wsize=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, wsize);
+printk("smb_writepage_sync: file %s/%s, count=%d@%Ld, wsize=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, count, loffset, wsize);
 #endif
 
+	if (!(file->f_flags & O_LARGEFILE) &&
+	    !off_t_presentable(loffset+1))
+	  /* Write starts beyond allowed type-range of off_t */
+	  return -EFBIG; /* Might trap at 2G, or might go above .. */
+
+	if (!(file->f_flags & O_LARGEFILE) &&
+	    !off_t_presentable(loffset + count))
+	  /* Writing beyond LargeFile maximums without O_LARGEFILE */
+	  count = LONG_MAX - loffset;
+
+	if (loffset >= 0x7fffffffULL) /* 2G-1 */
+	  return -EFBIG;
+	if ((loffset + count) >= 0x7fffffffULL)
+	  count = 0x7fffffffULL - loffset;
+
 	do {
 		if (count < wsize)
 			wsize = count;
 
-		result = smb_proc_write(dentry, offset, wsize, buffer);
+		result = smb_proc_write(dentry, loffset, wsize, buffer);
 		if (result < 0)
 			break;
 		/* N.B. what if result < wsize?? */
@@ -147,15 +165,15 @@
 printk("smb_writepage_sync: short write, wsize=%d, result=%d\n", wsize, result);
 #endif
 		buffer += wsize;
-		offset += wsize;
+		loffset += wsize;
 		written += wsize;
 		count -= wsize;
 		/*
 		 * Update the inode now rather than waiting for a refresh.
 		 */
 		inode->i_mtime = inode->i_atime = CURRENT_TIME;
-		if (offset > inode->i_size)
-			inode->i_size = offset;
+		if (loffset > inode->i_size)
+			inode->i_size = loffset;
 		inode->u.smbfs_i.cache_valid |= SMB_F_LOCALWRITE;
 	} while (count);
 	return written ? written : result;
@@ -170,7 +188,6 @@
 static int
 smb_writepage(struct file *file, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	int 	result;
 
 #ifdef SMBFS_PARANOIA
@@ -178,7 +195,7 @@
 		printk("smb_writepage: page not already locked!\n");
 #endif
 	get_page(page);
-	result = smb_writepage_sync(dentry, page, 0, PAGE_SIZE);
+	result = smb_writepage_sync(file, page, 0, PAGE_SIZE);
 	SetPageUptodate(page);
 	put_page(page);
 	return result;
@@ -189,11 +206,11 @@
 {
 	struct dentry *dentry = file->f_dentry;
 
-	pr_debug("SMBFS: smb_updatepage(%s/%s %d@%ld)\n",
+	pr_debug("SMBFS: smb_updatepage(%s/%s %d@%Ld)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-	 	count, (page->index << PAGE_CACHE_SHIFT)+offset);
+	 	count, (((loff_t)page->index) << PAGE_CACHE_SHIFT)+offset);
 
-	return smb_writepage_sync(dentry, page, offset, count);
+	return smb_writepage_sync(file, page, offset, count);
 }
 
 static ssize_t
@@ -203,9 +220,9 @@
 	ssize_t	status;
 
 #ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_file_read: file %s/%s, count=%lu@%lu\n",
+printk("smb_file_read: file %s/%s, count=%lu@%Lu\n",
 dentry->d_parent->d_name.name, dentry->d_name.name,
-(unsigned long) count, (unsigned long) *ppos);
+(unsigned long) count, *ppos);
 #endif
 
 	status = smb_revalidate_inode(dentry);
@@ -286,9 +303,9 @@
 	ssize_t	result;
 
 #ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_file_write: file %s/%s, count=%lu@%lu, pages=%ld\n",
+printk("smb_file_write: file %s/%s, count=%lu@%Ld, pages=%ld\n",
 dentry->d_parent->d_name.name, dentry->d_name.name,
-(unsigned long) count, (unsigned long) *ppos, dentry->d_inode->i_nrpages);
+(unsigned long) count, *ppos, dentry->d_inode->i_nrpages);
 #endif
 
 	result = smb_revalidate_inode(dentry);
@@ -309,8 +326,8 @@
 	{
 		result = generic_file_write(file, buf, count, ppos, smb_write_one_page);
 #ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_file_write: pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
-(long) file->f_pos, dentry->d_inode->i_size, dentry->d_inode->i_mtime,
+printk("smb_file_write: pos=%Ld, size=%ld, mtime=%ld, atime=%ld\n",
+file->f_pos, dentry->d_inode->i_size, dentry->d_inode->i_mtime,
 dentry->d_inode->i_atime);
 #endif
 	}
@@ -367,6 +384,33 @@
 	return error;
 }
 
+ 
+long smb_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return SMB_MAXNAMELEN;
+	case _PC_NO_TRUNC:
+	  return 1;		/* UNIX-like semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 static struct file_operations smb_file_operations =
 {
 	NULL,			/* lseek - default */
@@ -408,4 +452,5 @@
 	smb_file_permission,	/* permission */
 	NULL,			/* smap */
 	smb_revalidate_inode,	/* revalidate */
+	smb_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/smbfs/inode.c linux-23027p1m1/fs/smbfs/inode.c
--- linux-23027p1/fs/smbfs/inode.c	Fri Oct 15 00:22:09 1999
+++ linux-23027p1m1/fs/smbfs/inode.c	Mon Nov  8 22:58:52 1999
@@ -33,7 +33,7 @@
 static void smb_put_inode(struct inode *);
 static void smb_delete_inode(struct inode *);
 static void smb_put_super(struct super_block *);
-static int  smb_statfs(struct super_block *, struct statfs *, int);
+static int  smb_statvfs(struct super_block *, struct statvfs64 *);
 static void smb_set_inode_attr(struct inode *, struct smb_fattr *);
 
 static struct super_operations smb_sops =
@@ -45,7 +45,7 @@
 	smb_notify_change,	/* notify change */
 	smb_put_super,		/* put superblock */
 	NULL,			/* write superblock */
-	smb_statfs,		/* stat filesystem */
+	smb_statvfs,		/* stat filesystem */
 	NULL			/* remount filesystem */
 };
 
@@ -427,19 +427,15 @@
 }
 
 static int
-smb_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+smb_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs attr;
+	smb_proc_dskattr(sb, buf);
 
-	memset(&attr, 0, sizeof(attr));
-
-	smb_proc_dskattr(sb, &attr);
-
-	attr.f_type = SMB_SUPER_MAGIC;
-	attr.f_files = -1;
-	attr.f_ffree = -1;
-	attr.f_namelen = SMB_MAXPATHLEN;
-	return copy_to_user(buf, &attr, bufsiz) ? -EFAULT : 0;
+	buf->f_type = SMB_SUPER_MAGIC;
+	buf->f_files = -1;
+	buf->f_ffree = -1;
+	buf->f_namelen = SMB_MAXPATHLEN;
+	return 0;
 }
 
 int
diff -ur linux-23027p1/fs/smbfs/proc.c linux-23027p1m1/fs/smbfs/proc.c
--- linux-23027p1/fs/smbfs/proc.c	Thu Jun 17 05:26:27 1999
+++ linux-23027p1m1/fs/smbfs/proc.c	Mon Nov  8 22:58:52 1999
@@ -1003,7 +1003,7 @@
    file-id would not be valid after a reconnection. */
 
 int
-smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
+smb_proc_read(struct dentry *dentry, loff_t offset, int count, char *data)
 {
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	__u16 returned_count, data_len;
@@ -1045,14 +1045,14 @@
 }
 
 int
-smb_proc_write(struct dentry *dentry, off_t offset, int count, const char *data)
+smb_proc_write(struct dentry *dentry, loff_t offset, int count, const char *data)
 {
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	int result;
 	__u8 *p;
 
 #if SMBFS_DEBUG_VERBOSE
-printk("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
+printk("smb_proc_write: file %s/%s, count=%d@%Ld, packet_size=%d\n",
        DENTRY_PATH(dentry), count, offset, server->packet_size);
 #endif
 	smb_lock_server(server);
@@ -2234,7 +2234,7 @@
 }
 
 int
-smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
+smb_proc_dskattr(struct super_block *sb, struct statvfs64 *attr)
 {
 	struct smb_sb_info *server = &(sb->u.smbfs_sb);
 	int error;
diff -ur linux-23027p1/fs/stat.c linux-23027p1m1/fs/stat.c
--- linux-23027p1/fs/stat.c	Mon Aug 23 21:15:53 1999
+++ linux-23027p1m1/fs/stat.c	Mon Nov  8 22:58:52 1999
@@ -8,10 +8,22 @@
 #include <linux/errno.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
 /*
+ *  Large File Summit rules tell that fstat() with insufficient st_size
+ *  value space shall fail with  errno=EOVERFLOW,  while other *stat()
+ *  calls just return some arbitary value (e.g. MAXINT) at the same field.
+ *  This constant tells to behave differently.
+ *
+ */
+#define  all_fail_alike_fstat  0
+
+
+
+/*
  * Revalidate the inode. This is required for proper NFS attribute caching.
  */
 static __inline__ int
@@ -28,7 +40,7 @@
 
 /*
  * For backward compatibility?  Maybe this should be moved
- * into arch/i386 instead?
+ * into arch/i386 instead?  (and to m68k ???)
  */
 static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
 {
@@ -57,7 +69,12 @@
 
 #endif
 
-static int cp_new_stat(struct inode * inode, struct stat * statbuf)
+/* "No lie" policy yields EOVERFLOW if file size exceeds
+   a value which is presentable in field st_size (or st_blocks,
+   or st_ino). But then the file will not appear in the directory
+   listing at all before we have stat64() syscalls in use.. */
+
+static int cp_new_stat(struct inode * inode, struct stat * statbuf, int f)
 {
 	struct stat tmp;
 	unsigned int blocks, indirect;
@@ -65,12 +82,29 @@
 	memset(&tmp, 0, sizeof(tmp));
 	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
 	tmp.st_ino = inode->i_ino;
+	if (tmp.st_ino != inode->i_ino) {
+		if (f || all_fail_alike_fstat)
+			return -EOVERFLOW; /* See LFS spec: 2.2.1.14
+					      Xstat() shall fail with
+					      EOVERFLOW. */
+	  tmp.st_ino = -1;
+	}
 	tmp.st_mode = inode->i_mode;
 	tmp.st_nlink = inode->i_nlink;
 	tmp.st_uid = inode->i_uid;
 	tmp.st_gid = inode->i_gid;
 	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+	/* large-file stat() problem...
+	   If your file size is 4G-1, it *propably*
+	   is over 4G in a 32-bit system... */
 	tmp.st_size = inode->i_size;
+	if (inode->i_size != tmp.st_size) {
+		if (f || all_fail_alike_fstat)
+			return -EOVERFLOW; /* See LFS spec: 2.2.1.14
+					      Xstat() shall fail with
+					      EOVERFLOW. */
+		tmp.st_size = ULONG_MAX;
+	}
 	tmp.st_atime = inode->i_atime;
 	tmp.st_mtime = inode->i_mtime;
 	tmp.st_ctime = inode->i_ctime;
@@ -110,6 +144,15 @@
 		tmp.st_blocks = inode->i_blocks;
 		tmp.st_blksize = inode->i_blksize;
 	}
+#if BITS_PER_LONG < 64
+	if (tmp.st_blocks != inode->i_blocks) {
+		if (f || all_fail_alike_fstat)
+			return -EOVERFLOW; /* See LFS spec: 2.2.1.14
+					      Xstat() shall fail with
+					      EOVERFLOW. */
+		tmp.st_blocks = ULONG_MAX;
+	}
+#endif
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
@@ -152,7 +195,7 @@
 	if (!IS_ERR(dentry)) {
 		error = do_revalidate(dentry);
 		if (!error)
-			error = cp_new_stat(dentry->d_inode, statbuf);
+			error = cp_new_stat(dentry->d_inode, statbuf, 0);
 
 		dput(dentry);
 	}
@@ -200,7 +243,7 @@
 	if (!IS_ERR(dentry)) {
 		error = do_revalidate(dentry);
 		if (!error)
-			error = cp_new_stat(dentry->d_inode, statbuf);
+			error = cp_new_stat(dentry->d_inode, statbuf, 0);
 
 		dput(dentry);
 	}
@@ -247,7 +290,7 @@
 
 		err = do_revalidate(dentry);
 		if (!err)
-			err = cp_new_stat(dentry->d_inode, statbuf);
+			err = cp_new_stat(dentry->d_inode, statbuf, 1);
 		fput(f);
 	}
 	unlock_kernel();
@@ -279,4 +322,249 @@
 	}
 	unlock_kernel();
 	return error;
+}
+
+
+/* ---------- LFS-64 ----------- */
+
+static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf)
+{
+	struct stat64 tmp;
+	unsigned int blocks, indirect;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
+	tmp.st_ino = inode->i_ino;
+	tmp.st_mode = inode->i_mode;
+	tmp.st_nlink = inode->i_nlink;
+	tmp.st_uid = inode->i_uid;
+	tmp.st_gid = inode->i_gid;
+	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+	tmp.st_atime = inode->i_atime;
+	tmp.st_mtime = inode->i_mtime;
+	tmp.st_ctime = inode->i_ctime;
+	tmp.st_size = inode->i_size;
+/*
+ * st_blocks and st_blksize are approximated with a simple algorithm if
+ * they aren't supported directly by the filesystem. The minix and msdos
+ * filesystems don't keep track of blocks, so they would either have to
+ * be counted explicitly (by delving into the file itself), or by using
+ * this simple algorithm to get a reasonable (although not 100% accurate)
+ * value.
+ */
+
+/*
+ * Use minix fs values for the number of direct and indirect blocks.  The
+ * count is now exact for the minix fs except that it counts zero blocks.
+ * Everything is in units of BLOCK_SIZE until the assignment to
+ * tmp.st_blksize.
+ */
+#define D_B   7
+#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
+
+	if (!inode->i_blksize) {
+		blocks = (tmp.st_size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
+		if (blocks > D_B) {
+			indirect = (blocks - D_B + I_B - 1) / I_B;
+			blocks += indirect;
+			if (indirect > 1) {
+				indirect = (indirect - 1 + I_B - 1) / I_B;
+				blocks += indirect;
+				if (indirect > 1)
+					blocks++;
+			}
+		}
+		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
+		tmp.st_blksize = BLOCK_SIZE;
+	} else {
+		tmp.st_blocks = inode->i_blocks;
+		tmp.st_blksize = inode->i_blksize;
+	}
+	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_newstat64(char * filename, struct stat64 * statbuf, long flags)
+{
+	struct dentry * dentry;
+	int error;
+
+	lock_kernel();
+	dentry = namei(filename);
+
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		error = do_revalidate(dentry);
+		if (!error)
+			error = cp_new_stat64(dentry->d_inode, statbuf);
+
+		dput(dentry);
+	}
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage long sys_newlstat64(char * filename, struct stat64 * statbuf, long flags)
+{
+	struct dentry * dentry;
+	int error;
+
+	lock_kernel();
+	dentry = lnamei(filename);
+
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		error = do_revalidate(dentry);
+		if (!error)
+			error = cp_new_stat64(dentry->d_inode, statbuf);
+
+		dput(dentry);
+	}
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage long sys_newfstat64(unsigned long fd, struct stat64 * statbuf, long flags)
+{
+	struct file * f;
+	int err = -EBADF;
+
+	lock_kernel();
+	f = fget(fd);
+	if (f) {
+		struct dentry * dentry = f->f_dentry;
+
+		err = do_revalidate(dentry);
+		if (!err)
+			err = cp_new_stat64(dentry->d_inode, statbuf);
+		fput(f);
+	}
+	unlock_kernel();
+	return err;
+}
+
+
+
+/*
+ * POSIX pathconf()
+ *
+ * return value rules differ from sysconf(); If no explicite limit
+ * is in effect for given option,  pathconf()  shall return -1 without
+ * touching errno.  If the failure is anywhere else, errors like EINVAL,
+ * EACCESS, ENOENT,  etc. are possible..
+ *
+ * Returning ``-1'' without errno is indicated by returning ``-INT_MAX''
+ */
+
+extern long pipe_pathconf(struct inode *inode, long option);
+extern __u32 sysctl_wmem_max;
+
+static long dpathconf(struct dentry *dentry, long option)
+{
+	int (*pathconf)(struct inode*, int);
+	umode_t mode = dentry->d_inode->i_mode;
+
+	switch (option) {
+	case _PC_ASYNC_IO:	/* POSIX.4: TTY only (per Solaris) */
+	case _PC_PRIO_IO:
+	case _PC_MAX_CANON:	/* POSIX.1: TTY only */
+	case _PC_MAX_INPUT:
+	case _PC_VDISABLE:
+		if (!S_ISCHR(mode)) /* CHAR devices -- at least */
+			return -EINVAL;
+		break;
+
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	case _PC_NO_TRUNC:
+		if (!S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	case _PC_PATH_MAX:
+		if (!S_ISDIR(mode))
+			return -EINVAL;
+		return PATH_MAX;
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		if (!S_ISREG(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	case _PC_PIPE_BUF:	/* POSIX.1: Pipes & dirs only */
+		if (!S_ISFIFO(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		/* This direct call to pipe_pathconf() is done this
+		   way, because with named pipes the names may exist
+		   in some remote directories, but the pipes them-
+		   selves live only in the local system kernel */
+		return pipe_pathconf(dentry->d_inode, option);
+
+	case _PC_SOCK_MAXBUF:	/* POSIX.1g: fpathconf() */
+		if (!S_ISSOCK(mode))
+			return -EINVAL;
+		return sysctl_wmem_max;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		if (!S_ISREG(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only */
+		/* Solaris: Dirs ok too! */
+		if (!S_ISREG(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	default:		/* Eh ?? */
+		return -EINVAL;
+	}
+
+	pathconf = dentry->d_inode->i_op->pathconf;
+	if (pathconf)
+		return pathconf(dentry->d_inode, option);
+
+	return -EINVAL;	/* No pathconf, no direct processing! */
+}
+
+asmlinkage long sys_pathconf(char *pathname, long option)
+{
+	struct dentry * dentry;
+	int error;
+
+	lock_kernel();
+	dentry = namei(pathname);
+
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		error = do_revalidate(dentry);
+		if (!error)
+			error = dpathconf(dentry, option);
+		dput(dentry);
+	}
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * POSIX fpathconf() -- pathconf() with 'fd'
+ */
+
+asmlinkage long sys_fpathconf(long fd, long option)
+{
+	struct file * f;
+	int err;
+
+	lock_kernel();
+	f = fget(fd);
+	if (f) {
+		struct dentry * dentry = f->f_dentry;
+		
+		err = do_revalidate(dentry);
+		if (!err)
+			err = dpathconf(dentry, option);
+		fput(f);
+	} else
+		err = -EBADF;
+	unlock_kernel();
+	return err;
 }
diff -ur linux-23027p1/fs/super.c linux-23027p1m1/fs/super.c
--- linux-23027p1/fs/super.c	Sun Oct 31 09:19:22 1999
+++ linux-23027p1m1/fs/super.c	Mon Nov  8 22:58:52 1999
@@ -478,8 +478,7 @@
 {
         struct super_block *s;
         struct ustat tmp;
-        struct statfs sbuf;
-        mm_segment_t old_fs;
+        struct statvfs64 sbuf64;
 	int err = -EINVAL;
 
 	lock_kernel();
@@ -487,17 +486,14 @@
         if (s == NULL)
                 goto out;
 	err = -ENOSYS;
-        if (!(s->s_op->statfs))
+        if (!(s->s_op->statvfs))
                 goto out;
 
-        old_fs = get_fs();
-        set_fs(get_ds());
-        s->s_op->statfs(s,&sbuf,sizeof(struct statfs));
-        set_fs(old_fs);
+        s->s_op->statvfs(s,&sbuf64);
 
         memset(&tmp,0,sizeof(struct ustat));
-        tmp.f_tfree = sbuf.f_bfree;
-        tmp.f_tinode = sbuf.f_ffree;
+        tmp.f_tfree = sbuf64.f_bfree;
+        tmp.f_tinode = sbuf64.f_ffree;
 
         err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0;
 out:
diff -ur linux-23027p1/fs/sysv/dir.c linux-23027p1m1/fs/sysv/dir.c
--- linux-23027p1/fs/sysv/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/sysv/dir.c	Mon Nov  8 22:58:52 1999
@@ -18,6 +18,7 @@
 #include <linux/sysv_fs.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -28,6 +29,7 @@
 }
 
 static int sysv_readdir(struct file *, void *, filldir_t);
+extern long sysv_pathconf(struct inode *inode, long option);
 
 static struct file_operations sysv_dir_operations = {
 	NULL,			/* lseek - default */
@@ -66,7 +68,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	sysv_pathconf,		/* pathconf */
 };
 
 static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
@@ -114,4 +117,30 @@
 		brelse(bh);
 	}
 	return 0;
+}
+
+long sysv_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return SYSV_NAMELEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return !inode->i_sb->sv_truncate;
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return inode->i_sb->sv_link_max;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/sysv/file.c linux-23027p1m1/fs/sysv/file.c
--- linux-23027p1/fs/sysv/file.c	Tue Jul  6 06:35:18 1999
+++ linux-23027p1m1/fs/sysv/file.c	Mon Nov  8 22:58:52 1999
@@ -40,6 +40,8 @@
 				  ppos, block_write_partial_page);
 }
 
+extern long sysv_pathconf(struct inode *, long);
+
 /*
  * We have mostly NULLs here: the current defaults are OK for
  * the coh filesystem.
@@ -81,5 +83,6 @@
 	sysv_truncate,		/* truncate */
 	NULL,   		/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	sysv_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/sysv/inode.c linux-23027p1m1/fs/sysv/inode.c
--- linux-23027p1/fs/sysv/inode.c	Thu Oct  7 20:17:09 1999
+++ linux-23027p1m1/fs/sysv/inode.c	Mon Nov  8 22:58:52 1999
@@ -67,7 +67,7 @@
 static void sysv_write_super(struct super_block *);
 static void sysv_read_inode(struct inode *);
 static int sysv_notify_change(struct dentry *, struct iattr *);
-static int sysv_statfs(struct super_block *, struct statfs *, int);
+static int sysv_statvfs(struct super_block *, struct statvfs64 *);
 
 static struct super_operations sysv_sops = {
 	sysv_read_inode,
@@ -77,7 +77,7 @@
 	sysv_notify_change,
 	sysv_put_super,
 	sysv_write_super,
-	sysv_statfs,
+	sysv_statvfs,
 	NULL			/* remount_fs */
 };
 
@@ -564,20 +564,18 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static int sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+static int sysv_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	struct statfs tmp;
-
-	tmp.f_type = sb->s_magic;			/* type of filesystem */
-	tmp.f_bsize = sb->sv_block_size;		/* block size */
-	tmp.f_blocks = sb->sv_ndatazones;		/* total data blocks in file system */
-	tmp.f_bfree = sysv_count_free_blocks(sb);	/* free blocks in fs */
-	tmp.f_bavail = tmp.f_bfree;			/* free blocks available to non-superuser */
-	tmp.f_files = sb->sv_ninodes;			/* total file nodes in file system */
-	tmp.f_ffree = sysv_count_free_inodes(sb);	/* free file nodes in fs */
-	tmp.f_namelen = SYSV_NAMELEN;
-	/* Don't know what value to put in tmp.f_fsid */ /* file system id */
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_type = sb->s_magic;			/* type of filesystem */
+	buf->f_bsize = sb->sv_block_size;		/* block size */
+	buf->f_blocks = sb->sv_ndatazones;		/* total data blocks in file system */
+	buf->f_bfree = sysv_count_free_blocks(sb);	/* free blocks in fs */
+	buf->f_bavail = buf->f_bfree;			/* free blocks available to non-superuser */
+	buf->f_files = sb->sv_ninodes;			/* total file nodes in file system */
+	buf->f_ffree = sysv_count_free_inodes(sb);	/* free file nodes in fs */
+	buf->f_namelen = SYSV_NAMELEN;
+	/* Don't know what value to put in buf->f_fsid */ /* file system id */
+	return 0;
 }
 
 
diff -ur linux-23027p1/fs/sysv/symlink.c linux-23027p1m1/fs/sysv/symlink.c
--- linux-23027p1/fs/sysv/symlink.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/sysv/symlink.c	Mon Nov  8 22:58:52 1999
@@ -22,6 +22,7 @@
 
 static int sysv_readlink(struct dentry *, char *, int);
 static struct dentry *sysv_follow_link(struct dentry *, struct dentry *, unsigned int);
+extern long sysv_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -46,7 +47,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	sysv_pathconf,		/* pathconf */
 };
 
 static struct dentry *sysv_follow_link(struct dentry * dentry,
diff -ur linux-23027p1/fs/udf/super.c linux-23027p1m1/fs/udf/super.c
--- linux-23027p1/fs/udf/super.c	Sat Nov  6 19:51:19 1999
+++ linux-23027p1m1/fs/udf/super.c	Mon Nov  8 22:58:52 1999
@@ -86,7 +86,7 @@
 static unsigned int udf_count_free(struct super_block *);
 
 /* version specific functions */
-static int udf_statfs(struct super_block *, struct statfs *, int);
+static int udf_statvfs(struct super_block *, struct statvfs64 *);
 
 /* UDF filesystem type */
 static struct file_system_type udf_fstype = {
@@ -114,7 +114,7 @@
 	NULL,				/* notify_change */
 	udf_put_super,		/* put_super */
 	NULL,				/* write_super */
-	udf_statfs,			/* statfs */
+	udf_statvfs,			/* statvfs */
 	udf_remount_fs,		/* remount_fs */
 	NULL,				/* clear_inode */
 	NULL,				/* umount_begin */
@@ -1508,36 +1508,27 @@
  *	Return info about the filesystem.
  *
  * DESCRIPTION
- *	Called by sys_statfs()
+ *	Called by sys_statvfs()
  *
  * HISTORY
  *	July 1, 1997 - Andrew E. Mileski
  *	Written, tested, and released.
  */
 static int
-udf_statfs(struct super_block *sb, struct statfs *buf, int bufsize)
+udf_statvfs(struct super_block *sb, struct statvfs64 *buf)
 {
-	int size;
-	struct statfs tmp;
-	int rc;
-
-	size = (bufsize < sizeof(tmp)) ? bufsize: sizeof(tmp);
-
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.f_type = UDF_SUPER_MAGIC;
-	tmp.f_bsize = sb->s_blocksize;
-	tmp.f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
-	tmp.f_bfree = udf_count_free(sb);
-	tmp.f_bavail = tmp.f_bfree;
-	tmp.f_files = (UDF_SB_LVIDBH(sb) ?
+	buf->f_type = UDF_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
+	buf->f_bfree = udf_count_free(sb);
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = (UDF_SB_LVIDBH(sb) ?
 		(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) +
-		le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + tmp.f_bfree;
-	tmp.f_ffree = tmp.f_bfree;
+		le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + buf->f_bfree;
+	buf->f_ffree = buf->f_bfree;
 	/* __kernel_fsid_t f_fsid */
-	tmp.f_namelen = UDF_NAME_LEN;
-
-	rc= copy_to_user(buf, &tmp, size) ? -EFAULT: 0;
-	return rc;
+	buf->f_namelen = UDF_NAME_LEN;
+	return 0;
 }
 
 static unsigned char udf_bitmap_lookup[16] = {
diff -ur linux-23027p1/fs/ufs/balloc.c linux-23027p1m1/fs/ufs/balloc.c
--- linux-23027p1/fs/ufs/balloc.c	Tue Jul  6 05:59:55 1999
+++ linux-23027p1m1/fs/ufs/balloc.c	Mon Nov  8 22:58:52 1999
@@ -676,7 +676,7 @@
 	else
 		start = ucpi->c_frotor >> 3;
 		
-	length = howmany(uspi->s_fpg, 8) - start;
+	length = ((uspi->s_fpg + 7) >> 3) - start;
 	location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff + start, length,
 		(uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other,
 		1 << (count - 1 + (uspi->s_fpb & 7))); 
diff -ur linux-23027p1/fs/ufs/dir.c linux-23027p1m1/fs/ufs/dir.c
--- linux-23027p1/fs/ufs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/ufs/dir.c	Mon Nov  8 22:58:52 1999
@@ -18,6 +18,7 @@
 
 #include "swab.h"
 #include "util.h"
+#include <linux/unistd.h>
 
 #undef UFS_DIR_DEBUG
 
@@ -168,7 +169,7 @@
 		error_msg = "inode out of bounds";
 
 	if (error_msg != NULL)
-		ufs_error (sb, function, "bad entry in directory #%lu, size %lu: %s - "
+		ufs_error (sb, function, "bad entry in directory #%lu, size %Lu: %s - "
 			    "offset=%lu, inode=%lu, reclen=%d, namlen=%d",
 			    dir->i_ino, dir->i_size, error_msg, offset,
 			    (unsigned long) SWAB32(de->d_ino),
@@ -177,6 +178,32 @@
 	return (error_msg == NULL ? 1 : 0);
 }
 
+long ufs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return UFS_MAXNAMLEN; /* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* UNIX semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 64; /* FIXME: L-F-S:  mount-option: nolargefiles ? */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return UFS_LINK_MAX;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 static struct file_operations ufs_dir_operations = {
 	NULL,			/* lseek */
 	NULL,			/* read */
@@ -214,5 +241,6 @@
 	NULL,			/* truncate */
 	ufs_permission,		/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ufs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/ufs/file.c linux-23027p1m1/fs/ufs/file.c
--- linux-23027p1/fs/ufs/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/ufs/file.c	Mon Nov  8 22:58:52 1999
@@ -137,6 +137,8 @@
 	NULL			/* revalidate */
 };
 
+extern long ufs_pathconf(struct inode *, long);
+
 struct inode_operations ufs_file_inode_operations = {
 	&ufs_file_operations,/* default file operations */
 	NULL,			/* create */
@@ -157,5 +159,6 @@
 	ufs_truncate,		/* truncate */
 	NULL, 			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ufs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/ufs/inode.c linux-23027p1m1/fs/ufs/inode.c
--- linux-23027p1/fs/ufs/inode.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/ufs/inode.c	Mon Nov  8 22:58:52 1999
@@ -55,7 +55,7 @@
 {
 	unsigned swab = inode->i_sb->u.ufs_sb.s_swab;
 	printk("ino %lu  mode 0%6.6o  nlink %d  uid %d  uid32 %u"
-	       "  gid %d  gid32 %u  size %lu blocks %lu\n",
+	       "  gid %d  gid32 %u  size %Lu blocks %lu\n",
 	       inode->i_ino, inode->i_mode, inode->i_nlink,
 	       inode->i_uid, inode->u.ufs_i.i_uid, inode->i_gid, 
 	       inode->u.ufs_i.i_gid, inode->i_size, inode->i_blocks);
@@ -222,13 +222,10 @@
 	}
 	*err = -EFBIG;
 
-	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-	if (limit < RLIM_INFINITY) {
-		limit >>= sb->s_blocksize_bits;
-		if (new_fragment >= limit) {
-			send_sig(SIGXFSZ, current, 0);
-			return NULL;
-		}
+	limit = (current->rlimfsz.rlim_cur >> sb->s_blocksize_bits);
+	if (new_fragment >= limit) {
+		send_sig(SIGXFSZ, current, 0);
+		return NULL;
 	}
 
 	lastblock = ufs_fragstoblks (lastfrag);
@@ -319,7 +316,7 @@
 	block = ufs_fragstoblks (fragment);
 	blockoff = ufs_fragnum (fragment);
 
-	UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u\n", inode->i_ino, fragment, new_fragment))	
+	UFSD(("ENTER, ino %lu, fragment %u, new_fragment %u\n", inode->i_ino, fragment, new_fragment))
 
 	result = NULL;
 	if (!bh)
@@ -350,14 +347,12 @@
 	*err = -EFBIG;
 
 	{
-		unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-		if (limit < RLIM_INFINITY) {
-			limit >>= sb->s_blocksize_bits;
-			if (new_fragment >= limit) {
-				brelse (bh);
-				send_sig(SIGXFSZ, current, 0);
-				return NULL;
-			}
+		unsigned long limit = (current->rlimfsz.rlim_cur >> sb->s_blocksize_bits);
+		/* Infinity for this is rather 'large', even shifted down. */
+		if (new_fragment >= limit) {
+			brelse (bh);
+			send_sig(SIGXFSZ, current, 0);
+			return NULL;
 		}
 	}
 	if (block && (tmp = SWAB32(((u32*)bh->b_data)[block-1]) + uspi->s_fpb))
@@ -591,13 +586,11 @@
 	}
 	
 	/*
-	 * Linux i_size can be 32 on some architectures. We will mark 
-	 * big files as read only and let user access first 32 bits.
+	 * Linux i_size used to be 32 bits on some architectures.
+	 * These days we allow access to the entire file as is..
 	 */
 	inode->u.ufs_i.i_size = SWAB64(ufs_inode->ui_size);
-	inode->i_size = (off_t) inode->u.ufs_i.i_size;
-	if (sizeof(off_t) == 4 && (inode->u.ufs_i.i_size >> 32))
-		inode->i_size = (__u32)-1;
+	inode->i_size = inode->u.ufs_i.i_size;
 
 	inode->i_atime = SWAB32(ufs_inode->ui_atime.tv_sec);
 	inode->i_ctime = SWAB32(ufs_inode->ui_ctime.tv_sec);
@@ -610,7 +603,7 @@
 	inode->u.ufs_i.i_gen = SWAB32(ufs_inode->ui_gen);
 	inode->u.ufs_i.i_shadow = SWAB32(ufs_inode->ui_u3.ui_sun.ui_shadow);
 	inode->u.ufs_i.i_oeftflag = SWAB32(ufs_inode->ui_u3.ui_sun.ui_oeftflag);
-	inode->u.ufs_i.i_lastfrag = howmany (inode->i_size, uspi->s_fsize);
+	inode->u.ufs_i.i_lastfrag = (inode->i_size + uspi->s_fsize -1) >> uspi->s_fshift;
 	
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		;
diff -ur linux-23027p1/fs/ufs/super.c linux-23027p1m1/fs/ufs/super.c
--- linux-23027p1/fs/ufs/super.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/ufs/super.c	Mon Nov  8 22:58:52 1999
@@ -328,7 +328,7 @@
 	 * on the device. 
 	 */
 	size = uspi->s_cssize;
-	blks = howmany(size, uspi->s_fsize);
+	blks = (size + uspi->s_fsize-1) >> uspi->s_fshift;
 	base = space = kmalloc(size, GFP_KERNEL);
 	if (!base)
 		goto failed; 
@@ -405,7 +405,7 @@
 	uspi = sb->u.ufs_sb.s_uspi;
 
 	size = uspi->s_cssize;
-	blks = howmany(size, uspi->s_fsize);
+	blks = (size + uspi->s_fsize-1) >> uspi->s_fshift;
 	base = space = (char*) sb->u.ufs_sb.s_csp[0];
 	for (i = 0; i < blks; i += uspi->s_fpb) {
 		size = uspi->s_bsize;
@@ -892,28 +892,27 @@
 	return 0;
 }
 
-int ufs_statfs (struct super_block * sb, struct statfs * buf, int bufsiz)
+int ufs_statvfs (struct super_block * sb, struct statvfs64 * buf)
 {
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
-	struct statfs tmp;
 	unsigned swab;
 
 	swab = sb->u.ufs_sb.s_swab;
 	uspi = sb->u.ufs_sb.s_uspi;
 	usb1 = ubh_get_usb_first (USPI_UBH);
 	
-	tmp.f_type = UFS_MAGIC;
-	tmp.f_bsize = sb->s_blocksize;
-	tmp.f_blocks = uspi->s_dsize;
-	tmp.f_bfree = ufs_blkstofrags(SWAB32(usb1->fs_cstotal.cs_nbfree)) +
+	buf->f_type = UFS_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = uspi->s_dsize;
+	buf->f_bfree = ufs_blkstofrags(SWAB32(usb1->fs_cstotal.cs_nbfree)) +
 		SWAB32(usb1->fs_cstotal.cs_nffree);
-	tmp.f_bavail = (tmp.f_bfree > ((tmp.f_blocks / 100) * uspi->s_minfree))
-		? (tmp.f_bfree - ((tmp.f_blocks / 100) * uspi->s_minfree)) : 0;
-	tmp.f_files = uspi->s_ncg * uspi->s_ipg;
-	tmp.f_ffree = SWAB32(usb1->fs_cstotal.cs_nifree);
-	tmp.f_namelen = UFS_MAXNAMLEN;
-	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+	buf->f_bavail = (buf->f_bfree > (((u_long)buf->f_blocks / 100) * uspi->s_minfree))
+		? (buf->f_bfree - (((u_long)buf->f_blocks / 100) * uspi->s_minfree)) : 0;
+	buf->f_files = uspi->s_ncg * uspi->s_ipg;
+	buf->f_ffree = SWAB32(usb1->fs_cstotal.cs_nifree);
+	buf->f_namelen = UFS_MAXNAMLEN;
+	return 0;
 }
 
 static struct super_operations ufs_super_ops = {
@@ -924,7 +923,7 @@
 	NULL,			/* notify_change() */
 	ufs_put_super,
 	ufs_write_super,
-	ufs_statfs,
+	ufs_statvfs,
 	ufs_remount
 };
 
diff -ur linux-23027p1/fs/ufs/symlink.c linux-23027p1m1/fs/ufs/symlink.c
--- linux-23027p1/fs/ufs/symlink.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/ufs/symlink.c	Mon Nov  8 22:58:52 1999
@@ -116,6 +116,8 @@
 	return i;
 }
 
+extern long ufs_pathconf(struct inode *, long);
+
 struct inode_operations ufs_symlink_inode_operations = {
 	NULL,			/* no file-operations */
 	NULL,			/* create */
@@ -136,5 +138,6 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ufs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/ufs/truncate.c linux-23027p1m1/fs/ufs/truncate.c
--- linux-23027p1/fs/ufs/truncate.c	Wed Aug 18 20:15:19 1999
+++ linux-23027p1m1/fs/ufs/truncate.c	Mon Nov  8 22:58:52 1999
@@ -59,8 +59,8 @@
  *		Linus
  */
 
-#define DIRECT_BLOCK howmany (inode->i_size, uspi->s_bsize)
-#define DIRECT_FRAGMENT howmany (inode->i_size, uspi->s_fsize)
+#define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize -1) >> uspi->s_bshift)
+#define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize -1) >> uspi->s_fshift)
 
 #define DATA_BUFFER_USED(bh) \
 	(atomic_read(&bh->b_count) || buffer_locked(bh))
@@ -312,7 +312,7 @@
 	uspi = sb->u.ufs_sb.s_uspi;
 
 	dindirect_block = (DIRECT_BLOCK > offset) 
-		? ((DIRECT_BLOCK - offset) / uspi->s_apb) : 0;
+		? ((DIRECT_BLOCK - offset) >> uspi->s_apbshift) : 0;
 	retry = 0;
 	
 	tmp = SWAB32(*p);
@@ -382,7 +382,7 @@
 	retry = 0;
 	
 	tindirect_block = (DIRECT_BLOCK > (UFS_NDADDR + uspi->s_apb + uspi->s_2apb))
-		? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) / uspi->s_2apb) : 0;
+		? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) >> uspi->s_2apbshift) : 0;
 	p = inode->u.ufs_i.i_u1.i_data + UFS_TIND_BLOCK;
 	if (!(tmp = SWAB32(*p)))
 		return 0;
@@ -471,7 +471,8 @@
 		}
 	}
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	inode->u.ufs_i.i_lastfrag = howmany (inode->i_size, uspi->s_fsize);
+	inode->u.ufs_i.i_lastfrag =
+			(inode->i_size + uspi->s_fsize -1) >> uspi->s_fshift;
 	mark_inode_dirty(inode);
 	UFSD(("EXIT\n"))
 }
diff -ur linux-23027p1/fs/ufs/util.h linux-23027p1m1/fs/ufs/util.h
--- linux-23027p1/fs/ufs/util.h	Mon Nov  8 17:28:13 1999
+++ linux-23027p1m1/fs/ufs/util.h	Mon Nov  8 22:58:52 1999
@@ -14,7 +14,6 @@
  * some useful macros
  */
 #define in_range(b,first,len)	((b)>=(first)&&(b)<(first)+(len))
-#define howmany(x,y)		(((x)+(y)-1)/(y))
 #define min(x,y)		((x)<(y)?(x):(y))
 #define max(x,y)		((x)>(y)?(x):(y))
 
diff -ur linux-23027p1/fs/umsdos/dir.c linux-23027p1m1/fs/umsdos/dir.c
--- linux-23027p1/fs/umsdos/dir.c	Mon Aug  9 21:43:49 1999
+++ linux-23027p1m1/fs/umsdos/dir.c	Mon Nov  8 22:58:52 1999
@@ -16,6 +16,7 @@
 #include <linux/limits.h>
 #include <linux/umsdos_fs.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -801,6 +802,32 @@
 	goto out_free;
 }	
 
+ 
+static long umsdos_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return 256;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
 
 static struct file_operations umsdos_dir_operations =
 {
@@ -839,4 +866,5 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	umsdos_pathconf,	/* pathconf */
 };
diff -ur linux-23027p1/fs/umsdos/inode.c linux-23027p1m1/fs/umsdos/inode.c
--- linux-23027p1/fs/umsdos/inode.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/umsdos/inode.c	Mon Nov  8 22:58:52 1999
@@ -309,7 +309,7 @@
 	UMSDOS_notify_change,	/* notify_change */
 	UMSDOS_put_super,	/* put_super */
 	NULL,			/* write_super */
-	fat_statfs,		/* statfs */
+	fat_statvfs,		/* statvfs */
 	NULL,			/* remount_fs */
 	fat_clear_inode,	/* clear_inode */
 };
diff -ur linux-23027p1/fs/vfat/namei.c linux-23027p1m1/fs/vfat/namei.c
--- linux-23027p1/fs/vfat/namei.c	Mon Aug  9 21:43:49 1999
+++ linux-23027p1m1/fs/vfat/namei.c	Mon Nov  8 22:58:52 1999
@@ -23,6 +23,7 @@
 #include <linux/stat.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 #include "../fat/msbuffer.h"
 
@@ -1187,6 +1188,31 @@
 
 }
 
+static long vfat_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return 256;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
 
 /* Public inode operations for the VFAT fs */
 struct inode_operations vfat_dir_inode_operations = {
@@ -1209,7 +1235,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	vfat_pathconf,		/* pathconf */
 };
 
 struct super_block *vfat_read_super(struct super_block *sb,void *data,
diff -ur linux-23027p1/include/asm-alpha/fcntl.h linux-23027p1m1/include/asm-alpha/fcntl.h
--- linux-23027p1/include/asm-alpha/fcntl.h	Wed Oct 21 20:02:48 1998
+++ linux-23027p1m1/include/asm-alpha/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -20,6 +20,7 @@
 #define O_DIRECT	040000	/* direct disk access - should check with OSF/1 */
 #define O_DIRECTORY	0100000	/* must be a directory */
 #define O_NOFOLLOW	0200000 /* don't follow links */
+#define O_LARGEFILE     0400000 /* 64-bit offsets ok -- default at Alpha */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -35,6 +36,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -60,6 +65,14 @@
 	__kernel_off_t l_start;
 	__kernel_off_t l_len;
 	__kernel_pid_t l_pid;
+};
+
+struct flock64 {
+	int     l_type;
+	int     l_whence;
+	off64_t l_start;
+	off64_t l_len;
+	int     l_pid;
 };
 
 #endif
diff -ur linux-23027p1/include/asm-alpha/posix_types.h linux-23027p1m1/include/asm-alpha/posix_types.h
--- linux-23027p1/include/asm-alpha/posix_types.h	Fri Aug 21 16:33:36 1998
+++ linux-23027p1m1/include/asm-alpha/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -9,9 +9,11 @@
 
 typedef unsigned int	__kernel_dev_t;
 typedef unsigned int	__kernel_ino_t;
+typedef unsigned long	__kernel_ino64_t;
 typedef unsigned int	__kernel_mode_t;
 typedef unsigned int	__kernel_nlink_t;
 typedef long		__kernel_off_t;
+typedef long		__kernel_off64_t;
 typedef int		__kernel_pid_t;
 typedef int		__kernel_ipc_pid_t;
 typedef unsigned int	__kernel_uid_t;
diff -ur linux-23027p1/include/asm-alpha/statfs.h linux-23027p1m1/include/asm-alpha/statfs.h
--- linux-23027p1/include/asm-alpha/statfs.h	Sun Aug 18 10:42:02 1996
+++ linux-23027p1m1/include/asm-alpha/statfs.h	Mon Nov  8 22:58:52 1999
@@ -22,4 +22,17 @@
 	int f_spare[6];
 };
 
+struct statvfs64 {
+	int f_type;
+	int f_bsize;
+	__u64 f_blocks;
+	__u64 f_bfree;
+	__u64 f_bavail;
+	__u64 f_files;
+	__u64 f_ffree;
+	__kernel_fsid_t f_fsid;
+	int f_namelen;
+	int f_spare[6];
+};
+
 #endif
diff -ur linux-23027p1/include/asm-arm/fcntl.h linux-23027p1m1/include/asm-arm/fcntl.h
--- linux-23027p1/include/asm-arm/fcntl.h	Wed Oct 21 23:30:46 1998
+++ linux-23027p1m1/include/asm-arm/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -18,6 +18,7 @@
 #define FASYNC		020000	/* fcntl, for BSD compatibility */
 #define O_DIRECTORY	040000	/* must be a directory */
 #define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_LARGEFILE	0200000 /* file sizes exceeding 32-bit signed value */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -33,6 +34,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -58,6 +63,14 @@
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	int    l_type;
+	int    l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	int    l_pid;
 };
 
 #endif
diff -ur linux-23027p1/include/asm-arm/posix_types.h linux-23027p1m1/include/asm-arm/posix_types.h
--- linux-23027p1/include/asm-arm/posix_types.h	Sat May  8 21:06:57 1999
+++ linux-23027p1m1/include/asm-arm/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -17,9 +17,11 @@
 
 typedef unsigned short		__kernel_dev_t;
 typedef unsigned long		__kernel_ino_t;
+typedef unsigned long long	__kernel_ino64_t;
 typedef unsigned short		__kernel_mode_t;
 typedef unsigned short		__kernel_nlink_t;
 typedef long			__kernel_off_t;
+typedef long long		__kernel_off64_t;
 typedef int			__kernel_pid_t;
 typedef unsigned short		__kernel_ipc_pid_t;
 typedef unsigned short		__kernel_uid_t;
diff -ur linux-23027p1/include/asm-arm/statfs.h linux-23027p1m1/include/asm-arm/statfs.h
--- linux-23027p1/include/asm-arm/statfs.h	Wed Jan 21 02:39:43 1998
+++ linux-23027p1m1/include/asm-arm/statfs.h	Mon Nov  8 22:58:52 1999
@@ -22,4 +22,17 @@
 	long f_spare[6];
 };
 
+struct statvfs64 {
+	__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;
+	int f_namelen;
+	int f_spare[6];
+};
+
 #endif
diff -ur linux-23027p1/include/asm-i386/fcntl.h linux-23027p1m1/include/asm-i386/fcntl.h
--- linux-23027p1/include/asm-i386/fcntl.h	Wed Oct 21 20:02:48 1998
+++ linux-23027p1m1/include/asm-i386/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -35,6 +35,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -60,6 +64,14 @@
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	int    l_type;
+	int    l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	int    l_pid;
 };
 
 #endif
diff -ur linux-23027p1/include/asm-i386/posix_types.h linux-23027p1m1/include/asm-i386/posix_types.h
--- linux-23027p1/include/asm-i386/posix_types.h	Sun Dec 27 20:39:50 1998
+++ linux-23027p1m1/include/asm-i386/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -9,9 +9,11 @@
 
 typedef unsigned short	__kernel_dev_t;
 typedef unsigned long	__kernel_ino_t;
+typedef unsigned long long __kernel_ino64_t;
 typedef unsigned short	__kernel_mode_t;
 typedef unsigned short	__kernel_nlink_t;
 typedef long		__kernel_off_t;
+typedef long long	__kernel_off64_t;
 typedef int		__kernel_pid_t;
 typedef unsigned short	__kernel_ipc_pid_t;
 typedef unsigned short	__kernel_uid_t;
diff -ur linux-23027p1/include/asm-i386/statfs.h linux-23027p1m1/include/asm-i386/statfs.h
--- linux-23027p1/include/asm-i386/statfs.h	Mon Nov  8 14:11:09 1999
+++ linux-23027p1m1/include/asm-i386/statfs.h	Mon Nov  8 22:58:52 1999
@@ -22,4 +22,17 @@
 	long f_spare[6];
 };
 
+struct statvfs64 {
+	__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;
+	int f_namelen;
+	int f_spare[6];
+};
+
 #endif
diff -ur linux-23027p1/include/asm-m68k/fcntl.h linux-23027p1m1/include/asm-m68k/fcntl.h
--- linux-23027p1/include/asm-m68k/fcntl.h	Wed Oct 21 23:30:56 1998
+++ linux-23027p1m1/include/asm-m68k/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -18,6 +18,7 @@
 #define FASYNC		020000	/* fcntl, for BSD compatibility */
 #define O_DIRECTORY	040000	/* must be a directory */
 #define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_LARGEFILE	0200000 /* file sizes exceeding 32-bit signed value */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -33,6 +34,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -58,6 +63,14 @@
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	int    l_type;
+	int    l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	int    l_pid;
 };
 
 #endif /* _M68K_FCNTL_H */
diff -ur linux-23027p1/include/asm-m68k/posix_types.h linux-23027p1m1/include/asm-m68k/posix_types.h
--- linux-23027p1/include/asm-m68k/posix_types.h	Mon Aug 10 21:02:24 1998
+++ linux-23027p1m1/include/asm-m68k/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -9,9 +9,11 @@
 
 typedef unsigned short	__kernel_dev_t;
 typedef unsigned long	__kernel_ino_t;
+typedef unsigned long long __kernel_ino64_t;
 typedef unsigned short	__kernel_mode_t;
 typedef unsigned short	__kernel_nlink_t;
 typedef long		__kernel_off_t;
+typedef long long	__kernel_off64_t;
 typedef int		__kernel_pid_t;
 typedef unsigned short	__kernel_ipc_pid_t;
 typedef unsigned short	__kernel_uid_t;
diff -ur linux-23027p1/include/asm-m68k/statfs.h linux-23027p1m1/include/asm-m68k/statfs.h
--- linux-23027p1/include/asm-m68k/statfs.h	Mon Jun  3 10:09:13 1996
+++ linux-23027p1m1/include/asm-m68k/statfs.h	Mon Nov  8 22:58:52 1999
@@ -22,4 +22,17 @@
 	long f_spare[6];
 };
 
+struct statvfs64 {
+	__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;
+	int f_namelen;
+	int f_spare[6];
+};
+
 #endif /* _M68K_STATFS_H */
diff -ur linux-23027p1/include/asm-mips/fcntl.h linux-23027p1m1/include/asm-mips/fcntl.h
--- linux-23027p1/include/asm-mips/fcntl.h	Sat Jun 26 03:37:53 1999
+++ linux-23027p1m1/include/asm-mips/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -44,6 +44,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -72,5 +76,15 @@
 	__kernel_pid_t l_pid;
 	long  pad[4];			/* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
 } flock_t;
+
+typedef struct flock64 {
+	int   l_type;
+	int   l_whence;
+	__kernel_loff_t l_start;
+	__kernel_loff_t l_len;
+	long  l_sysid;			/* XXXXXXXXXXXXXXXXXXXXXXXXX */
+	__kernel_pid_t l_pid;
+	long  pad[4];			/* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
+} flock64_t;
 
 #endif /* __ASM_MIPS_FCNTL_H */
diff -ur linux-23027p1/include/asm-mips/posix_types.h linux-23027p1m1/include/asm-mips/posix_types.h
--- linux-23027p1/include/asm-mips/posix_types.h	Tue Oct 20 23:52:53 1998
+++ linux-23027p1m1/include/asm-mips/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -38,6 +38,8 @@
 typedef char *		__kernel_caddr_t;
 
 #ifdef __GNUC__
+typedef unsigned long long __kernel_ino64_t;
+typedef long long	__kernel_off64_t;
 typedef long long      __kernel_loff_t;
 #endif
 
diff -ur linux-23027p1/include/asm-mips/statfs.h linux-23027p1m1/include/asm-mips/statfs.h
--- linux-23027p1/include/asm-mips/statfs.h	Thu Jun 26 22:33:40 1997
+++ linux-23027p1m1/include/asm-mips/statfs.h	Mon Nov  8 22:58:52 1999
@@ -37,4 +37,21 @@
 	long		f_spare[6];
 };
 
+struct statvfs64 {
+	long		f_type;
+#define f_fstyp f_type
+	long		f_bsize;
+	__u64		f_frsize;	/* Fragment size - fs specific */
+	__u64		f_blocks;
+	__u64		f_bfree;
+	__u64		f_files;
+	__u64		f_ffree;
+
+	/* Linux specials */
+	__u64		f_bavail;
+	__kernel_fsid_t	f_fsid;
+	long		f_namelen;
+	long		f_spare[6];
+};
+
 #endif /* __ASM_MIPS_STATFS_H */
diff -ur linux-23027p1/include/asm-ppc/fcntl.h linux-23027p1m1/include/asm-ppc/fcntl.h
--- linux-23027p1/include/asm-ppc/fcntl.h	Wed Oct 21 23:31:06 1998
+++ linux-23027p1m1/include/asm-ppc/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -18,6 +18,7 @@
 #define FASYNC		020000	/* fcntl, for BSD compatibility */
 #define O_DIRECTORY	040000	/* must be a directory */
 #define O_NOFOLLOW	0100000	/* don't follow links */
+#define O_LARGEFILE	0200000 /* file sizes exceeding 'off_t' */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -33,6 +34,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -64,6 +69,14 @@
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	int    l_type;
+	int    l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	int    l_pid;
 };
 
 #endif
diff -ur linux-23027p1/include/asm-ppc/posix_types.h linux-23027p1m1/include/asm-ppc/posix_types.h
--- linux-23027p1/include/asm-ppc/posix_types.h	Thu Apr 29 22:39:01 1999
+++ linux-23027p1m1/include/asm-ppc/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -26,6 +26,8 @@
 typedef short             __kernel_ipc_pid_t;
 
 #ifdef __GNUC__
+typedef unsigned long long __kernel_ino64_t;
+typedef long long	__kernel_off64_t;
 typedef long long	__kernel_loff_t;
 #endif
 
diff -ur linux-23027p1/include/asm-ppc/statfs.h linux-23027p1m1/include/asm-ppc/statfs.h
--- linux-23027p1/include/asm-ppc/statfs.h	Mon Jun  3 10:09:13 1996
+++ linux-23027p1m1/include/asm-ppc/statfs.h	Mon Nov  8 22:58:52 1999
@@ -22,7 +22,17 @@
 	long f_spare[6];
 };
 
-#endif
-
-
+struct statvfs64 {
+	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_spare[6];
+};
 
+#endif
diff -ur linux-23027p1/include/asm-sparc/fcntl.h linux-23027p1m1/include/asm-sparc/fcntl.h
--- linux-23027p1/include/asm-sparc/fcntl.h	Tue Oct 27 19:52:21 1998
+++ linux-23027p1m1/include/asm-sparc/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -19,6 +19,7 @@
 #define O_NOCTTY	0x8000	/* not fcntl */
 #define O_DIRECTORY	0x10000	/* must be a directory */
 #define O_NOFOLLOW	0x20000	/* don't follow links */
+#define O_LARGEFILE	0x40000 /* file sizes exceeding 'off_t' range (2G) */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -33,6 +34,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -59,6 +64,14 @@
 	off_t l_len;
 	pid_t l_pid;
 	short __unused;
+};
+
+struct flock64 {
+	int    l_type;
+	int    l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	int    l_pid;
 };
 
 #endif
diff -ur linux-23027p1/include/asm-sparc/posix_types.h linux-23027p1m1/include/asm-sparc/posix_types.h
--- linux-23027p1/include/asm-sparc/posix_types.h	Thu Mar 11 02:53:37 1999
+++ linux-23027p1m1/include/asm-sparc/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -33,6 +33,8 @@
 typedef char *                 __kernel_caddr_t;
 
 #ifdef __GNUC__
+typedef unsigned long long     __kernel_ino64_t;
+typedef long long              __kernel_off64_t;
 typedef long long	__kernel_loff_t;
 #endif
 
diff -ur linux-23027p1/include/asm-sparc/statfs.h linux-23027p1m1/include/asm-sparc/statfs.h
--- linux-23027p1/include/asm-sparc/statfs.h	Sat Nov  9 21:39:33 1996
+++ linux-23027p1m1/include/asm-sparc/statfs.h	Mon Nov  8 22:58:52 1999
@@ -23,4 +23,17 @@
 	long f_spare[6];
 };
 
+struct statvfs64 {
+	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;  /* SunOS ignores this field. */
+	long f_spare[6];
+};
+
 #endif
diff -ur linux-23027p1/include/asm-sparc64/fcntl.h linux-23027p1m1/include/asm-sparc64/fcntl.h
--- linux-23027p1/include/asm-sparc64/fcntl.h	Tue Oct 27 19:52:21 1998
+++ linux-23027p1m1/include/asm-sparc64/fcntl.h	Mon Nov  8 22:58:52 1999
@@ -19,6 +19,7 @@
 #define O_NOCTTY	0x8000	/* not fcntl */
 #define O_DIRECTORY	0x10000	/* must be a directory */
 #define O_NOFOLLOW	0x20000	/* don't follow links */
+#define O_LARGEFILE	0x40000 /* file sizes exceeding 'off_t' range (2G) */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -33,6 +34,10 @@
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
 
+#define F_GETLK64	12	/*  using 'struct flock64' */
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
@@ -71,5 +76,13 @@
 	short __unused;
 };
 #endif
+
+struct flock64 {
+	int    l_type;
+	int    l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	int    l_pid;
+};
 
 #endif /* !(_SPARC64_FCNTL_H) */
diff -ur linux-23027p1/include/asm-sparc64/posix_types.h linux-23027p1m1/include/asm-sparc64/posix_types.h
--- linux-23027p1/include/asm-sparc64/posix_types.h	Thu Mar 11 02:53:38 1999
+++ linux-23027p1m1/include/asm-sparc64/posix_types.h	Mon Nov  8 22:58:52 1999
@@ -34,6 +34,8 @@
 typedef int		       __kernel_suseconds_t;
 
 #ifdef __GNUC__
+typedef unsigned long          __kernel_ino64_t;
+typedef long                   __kernel_off64_t;
 typedef long long              __kernel_loff_t;
 #endif
 
diff -ur linux-23027p1/include/asm-sparc64/statfs.h linux-23027p1m1/include/asm-sparc64/statfs.h
--- linux-23027p1/include/asm-sparc64/statfs.h	Thu Apr 24 05:01:28 1997
+++ linux-23027p1m1/include/asm-sparc64/statfs.h	Mon Nov  8 22:58:52 1999
@@ -36,4 +36,17 @@
 	long f_spare[6];
 };
 
+struct statvfs64 {
+	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_spare[6];
+};
+
 #endif
diff -ur linux-23027p1/include/linux/coda_psdev.h linux-23027p1m1/include/linux/coda_psdev.h
--- linux-23027p1/include/linux/coda_psdev.h	Wed Jul  7 05:08:33 1999
+++ linux-23027p1m1/include/linux/coda_psdev.h	Mon Nov  8 22:58:52 1999
@@ -80,7 +80,7 @@
 		 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_statvfs(struct super_block *sb, struct statvfs64 *sfs);
 
 
 /* messages between coda filesystem in kernel and Venus */
diff -ur linux-23027p1/include/linux/dirent.h linux-23027p1m1/include/linux/dirent.h
--- linux-23027p1/include/linux/dirent.h	Wed Jul 10 07:38:08 1996
+++ linux-23027p1m1/include/linux/dirent.h	Mon Nov  8 22:58:52 1999
@@ -8,4 +8,13 @@
 	char		d_name[256]; /* We must not include limits.h! */
 };
 
+struct dirent64 {
+	__u64		d_ino;		/* 64 bits *should* be enough */
+	__u32		d_off;		/* position within directory */
+	__u32		d_flags;	/* what is stored in  d_data[] */
+	__u32		d_data[8];	/* for future extensions */
+	__u16		d_reclen;
+	char		d_name[256];	/* We must not include limits.h! */
+};
+
 #endif
diff -ur linux-23027p1/include/linux/ext2_fs.h linux-23027p1m1/include/linux/ext2_fs.h
--- linux-23027p1/include/linux/ext2_fs.h	Mon Nov  8 14:11:09 1999
+++ linux-23027p1m1/include/linux/ext2_fs.h	Mon Nov  8 22:58:52 1999
@@ -598,7 +598,7 @@
 extern int ext2_remount (struct super_block *, int *, char *);
 extern struct super_block * ext2_read_super (struct super_block *,void *,int);
 extern int init_ext2_fs(void);
-extern int ext2_statfs (struct super_block *, struct statfs *, int);
+extern int ext2_statvfs (struct super_block *, struct statvfs64 *);
 
 /* truncate.c */
 extern void ext2_truncate (struct inode *);
diff -ur linux-23027p1/include/linux/fat_cvf.h linux-23027p1m1/include/linux/fat_cvf.h
--- linux-23027p1/include/linux/fat_cvf.h	Mon Aug  9 21:43:49 1999
+++ linux-23027p1m1/include/linux/fat_cvf.h	Mon Nov  8 22:58:52 1999
@@ -25,7 +25,7 @@
                         int nbreq,
                         struct buffer_head *bh[32]);
   int (*fat_access) (struct super_block *sb,int nr,int new_value);
-  int (*cvf_statfs) (struct super_block *sb,struct statfs *buf, int bufsiz);
+  int (*cvf_statvfs) (struct super_block *sb,struct statvfs64 *buf);
   int (*cvf_bmap) (struct inode *inode,int block);
   ssize_t (*cvf_file_read) ( struct file *, char *, size_t, loff_t *);
   ssize_t (*cvf_file_write) ( struct file *, const char *, size_t, loff_t *);
diff -ur linux-23027p1/include/linux/fs.h linux-23027p1m1/include/linux/fs.h
--- linux-23027p1/include/linux/fs.h	Mon Nov  8 22:57:35 1999
+++ linux-23027p1m1/include/linux/fs.h	Mon Nov  8 22:58:52 1999
@@ -249,6 +249,16 @@
 #define buffer_page(bh)		(mem_map + MAP_NR((bh)->b_data))
 #define touch_buffer(bh)	set_bit(PG_referenced, &buffer_page(bh)->flags)
 
+static int off_t_presentable(loff_t) __attribute__ ((const));
+static __inline__ int off_t_presentable(loff_t loff)
+{
+#if BITS_PER_LONG < 64
+	return (loff <= (loff_t)LONG_MAX);
+#else
+	return 1;
+#endif
+}
+
 #include <linux/pipe_fs_i.h>
 #include <linux/minix_fs_i.h>
 #include <linux/ext2_fs_i.h>
@@ -428,7 +438,25 @@
 	unsigned int 		f_flags;
 	mode_t			f_mode;
 	loff_t			f_pos;
-	unsigned long 		f_reada, f_ramax, f_raend, f_ralen, f_rawin;
+
+/*
+ * Read-ahead context:
+ * -------------------
+ * The read ahead context fields of the "struct file" are the following:
+ * - f_raend : index of the last+1 page after attempted read-ahead.
+ * - f_ramax : current read-ahead maximum size.
+ * - f_ralen : length of the current IO read block we tried to read-ahead.
+ * - f_rawin : length of the current read-ahead window.
+ *
+ * For more info, see  mm/filemap.c
+ */
+	int			f_reada;	/* bool */ /* all around   */
+	/* following u_long could be done with u_int as well, and
+	   have slightly smaller 'struct file' for 64-bit machines.
+	   Presuming, of course, that we stay under 2 GB read-ahead ... */
+	u_int			f_ramax, f_ralen, f_rawin; /* mm/filemap.c */
+	u_long	 		f_raend;		   /* mm/filemap.c */
+
 	struct fown_struct	f_owner;
 	unsigned int		f_uid, f_gid;
 	int			f_error;
@@ -474,8 +502,8 @@
 	struct file *fl_file;
 	unsigned char fl_flags;
 	unsigned char fl_type;
-	off_t fl_start;
-	off_t fl_end;
+	loff_t fl_start;
+	loff_t fl_end;
 
 	void (*fl_notify)(struct file_lock *);	/* unblock callback */
 
@@ -491,6 +519,9 @@
 extern int fcntl_getlk(unsigned int, struct flock *);
 extern int fcntl_setlk(unsigned int, unsigned int, struct flock *);
 
+extern int fcntl_getlk64(unsigned int fd, struct flock64 *l);
+extern int fcntl_setlk64(unsigned int fd, unsigned int cmd, struct flock64 *l);
+
 /* fs/locks.c */
 extern void locks_remove_posix(struct file *, fl_owner_t);
 extern void locks_remove_flock(struct file *);
@@ -655,6 +686,7 @@
 	int (*permission) (struct inode *, int);
 	int (*smap) (struct inode *,int);
 	int (*revalidate) (struct dentry *);
+	long (*pathconf) (struct inode *, long option);
 };
 
 struct super_operations {
@@ -665,7 +697,7 @@
 	int (*notify_change) (struct dentry *, struct iattr *);
 	void (*put_super) (struct super_block *);
 	void (*write_super) (struct super_block *);
-	int (*statfs) (struct super_block *, struct statfs *, int);
+	int (*statvfs) (struct super_block *, struct statvfs64 *);
 	int (*remount_fs) (struct super_block *, int *, char *);
 	void (*clear_inode) (struct inode *);
 	void (*umount_begin) (struct super_block *);
@@ -730,8 +762,8 @@
 
 asmlinkage long sys_open(const char *, int, int);
 asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
-extern int do_close(unsigned int, int);		/* yes, it's really unsigned */
-extern int do_truncate(struct dentry *, unsigned long);
+extern long do_close(unsigned int, int);	/* yes, it's really unsigned */
+extern long do_truncate(struct dentry *, loff_t);
 extern int get_unused_fd(void);
 extern void put_unused_fd(unsigned int);
 
@@ -978,7 +1010,7 @@
 
 extern int block_fsync(struct file *, struct dentry *);
 extern int file_fsync(struct file *, struct dentry *);
-extern int generic_buffer_fdatasync(struct inode *inode, unsigned long start, unsigned long end);
+extern int generic_buffer_fdatasync(struct inode *inode, loff_t start, loff_t end);
 
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern void inode_setattr(struct inode *, struct iattr *);
diff -ur linux-23027p1/include/linux/mm.h linux-23027p1m1/include/linux/mm.h
--- linux-23027p1/include/linux/mm.h	Mon Nov  8 14:11:15 1999
+++ linux-23027p1m1/include/linux/mm.h	Mon Nov  8 22:58:52 1999
@@ -324,7 +324,7 @@
 extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot);
 extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot);
 
-extern void vmtruncate(struct inode * inode, unsigned long offset);
+extern void vmtruncate(struct inode * inode, loff_t offset);
 extern int handle_mm_fault(struct task_struct *tsk,struct vm_area_struct *vma, unsigned long address, int write_access);
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
@@ -351,7 +351,7 @@
 extern unsigned long get_unmapped_area(unsigned long, unsigned long);
 
 extern unsigned long do_mmap(struct file *, unsigned long, unsigned long,
-	unsigned long, unsigned long, unsigned long);
+	unsigned long, unsigned long, loff_t);
 extern int do_munmap(unsigned long, size_t);
 extern unsigned long do_brk(unsigned long, unsigned long);
 
@@ -359,7 +359,7 @@
 extern void remove_inode_page(struct page *);
 extern unsigned long page_unuse(struct page *);
 extern int shrink_mmap(int, int);
-extern void truncate_inode_pages(struct inode *, unsigned long);
+extern void truncate_inode_pages(struct inode *, loff_t);
 extern void put_cached_page(unsigned long);
 
 /*
diff -ur linux-23027p1/include/linux/msdos_fs.h linux-23027p1m1/include/linux/msdos_fs.h
--- linux-23027p1/include/linux/msdos_fs.h	Mon Nov  8 14:14:22 1999
+++ linux-23027p1m1/include/linux/msdos_fs.h	Mon Nov  8 22:58:52 1999
@@ -247,7 +247,7 @@
 extern struct inode *fat_build_inode(struct super_block*,struct msdos_dir_entry*,int,int*);
 extern struct super_block *fat_read_super(struct super_block *s, void *data, int silent, struct inode_operations *dir_ops);
 extern void msdos_put_super(struct super_block *sb);
-extern int fat_statfs(struct super_block *sb,struct statfs *buf, int);
+extern int fat_statvfs(struct super_block *sb,struct statvfs64 *buf);
 extern void fat_write_inode(struct inode *inode);
 
 /* dir.c */
@@ -270,6 +270,7 @@
 extern ssize_t fat_file_read(struct file *, char *, size_t, loff_t *);
 extern ssize_t fat_file_write(struct file *, const char *, size_t, loff_t *);
 extern void fat_truncate(struct inode *inode);
+extern long fat_pathconf(struct inode *, long);
 
 /* mmap.c */
 extern int fat_mmap(struct file *, struct vm_area_struct *);
diff -ur linux-23027p1/include/linux/nfs.h linux-23027p1m1/include/linux/nfs.h
--- linux-23027p1/include/linux/nfs.h	Mon Oct 18 21:26:37 1999
+++ linux-23027p1m1/include/linux/nfs.h	Mon Nov  8 22:58:52 1999
@@ -111,7 +111,7 @@
 	__u32			nlink;
 	__u32			uid;
 	__u32			gid;
-	__u32			size;
+	__u64			size;
 	__u32			blocksize;
 	__u32			rdev;
 	__u32			blocks;
@@ -132,7 +132,7 @@
 
 struct nfs_writeargs {
 	struct nfs_fh *		fh;
-	__u32			offset;
+	__u64			offset;
 	__u32			count;
 	const void *		buffer;
 };
@@ -156,7 +156,7 @@
 
 struct nfs_readargs {
 	struct nfs_fh *		fh;
-	__u32			offset;
+	__u64			offset;
 	__u32			count;
 	void *			buffer;
 };
diff -ur linux-23027p1/include/linux/nfs_fs.h linux-23027p1m1/include/linux/nfs_fs.h
--- linux-23027p1/include/linux/nfs_fs.h	Mon Nov  8 14:11:45 1999
+++ linux-23027p1m1/include/linux/nfs_fs.h	Mon Nov  8 22:58:52 1999
@@ -145,10 +145,10 @@
 			const char *name, struct nfs_fh *fhandle,
 			struct nfs_fattr *fattr);
 extern int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
-			int swap, unsigned long offset, unsigned int count,
+			int swap, loff_t offset, unsigned int count,
 			void *buffer, struct nfs_fattr *fattr);
 extern int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
-			int swap, unsigned long offset, unsigned int count,
+			int swap, loff_t offset, unsigned int count,
 			const void *buffer, struct nfs_fattr *fattr);
 extern int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
 			const char *name, struct iattr *sattr,
@@ -168,7 +168,7 @@
 			struct nfs_fh *fhandle, struct nfs_fattr *fattr);
 extern int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir,
 			const char *name);
-extern int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
+extern int nfs_proc_statvfs(struct nfs_server *server, struct nfs_fh *fhandle,
 			struct nfs_fsinfo *res);
 
 
diff -ur linux-23027p1/include/linux/nfsd/nfsd.h linux-23027p1m1/include/linux/nfsd/nfsd.h
--- linux-23027p1/include/linux/nfsd/nfsd.h	Mon Nov  8 14:13:05 1999
+++ linux-23027p1m1/include/linux/nfsd/nfsd.h	Mon Nov  8 22:58:52 1999
@@ -105,8 +105,8 @@
 int		nfsd_readdir(struct svc_rqst *, struct svc_fh *,
 				loff_t, encode_dent_fn,
 				u32 *buffer, int *countp);
-int		nfsd_statfs(struct svc_rqst *, struct svc_fh *,
-				struct statfs *);
+int		nfsd_statvfs(struct svc_rqst *, struct svc_fh *,
+				struct statvfs64 *);
 int		nfsd_notify_change(struct inode *, struct iattr *);
 int		nfsd_permission(struct svc_export *, struct dentry *, int);
 
diff -ur linux-23027p1/include/linux/nfsd/xdr.h linux-23027p1m1/include/linux/nfsd/xdr.h
--- linux-23027p1/include/linux/nfsd/xdr.h	Mon Nov  8 14:13:05 1999
+++ linux-23027p1m1/include/linux/nfsd/xdr.h	Mon Nov  8 22:58:52 1999
@@ -101,7 +101,7 @@
 };
 
 struct nfsd_statfsres {
-	struct statfs		stats;
+	struct statvfs64	stats;
 };
 
 /*
diff -ur linux-23027p1/include/linux/nfsd/xdr3.h linux-23027p1m1/include/linux/nfsd/xdr3.h
--- linux-23027p1/include/linux/nfsd/xdr3.h	Mon Apr  7 21:35:32 1997
+++ linux-23027p1m1/include/linux/nfsd/xdr3.h	Mon Nov  8 22:58:52 1999
@@ -163,7 +163,7 @@
 
 struct nfsd3_statfsres {
 	__u32			status;
-	struct statfs		stats;
+	struct statvfs64	stats;
 	__u32			invarsec;
 };
 
diff -ur linux-23027p1/include/linux/proc_fs.h linux-23027p1m1/include/linux/proc_fs.h
--- linux-23027p1/include/linux/proc_fs.h	Mon Nov  8 22:57:35 1999
+++ linux-23027p1m1/include/linux/proc_fs.h	Mon Nov  8 22:58:52 1999
@@ -295,7 +295,7 @@
 extern struct super_block *proc_read_super(struct super_block *,void *,int);
 extern int init_proc_fs(void);
 extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *);
-extern int proc_statfs(struct super_block *, struct statfs *, int);
+extern int proc_statvfs(struct super_block *, struct statvfs64 *);
 extern void proc_read_inode(struct inode *);
 extern void proc_write_inode(struct inode *);
 
diff -ur linux-23027p1/include/linux/resource.h linux-23027p1m1/include/linux/resource.h
--- linux-23027p1/include/linux/resource.h	Mon Nov  8 14:11:09 1999
+++ linux-23027p1m1/include/linux/resource.h	Mon Nov  8 22:58:52 1999
@@ -43,11 +43,26 @@
  * Which makes a ton more sense anyway.
  */
 #define RLIM_INFINITY	(~0UL)
+#define RLIM_SAVED_MAX  ((~0UL)-1UL)
+#define RLIM_SAVED_CUR	((~0UL)-2UL)
+
+/* We compare against SIGNED 64-bit loff_t, better to limit ourself
+   to  2^63-1,  which is rather high value anyway... */
+#define RLIM64_INFINITY	((long long)((~0ULL) >> 1))
+#define RLIM64_SAVED_MAX RLIM64_INFINITY
+#define RLIM64_SAVED_CUR RLIM64_INFINITY
 
 struct rlimit {
 	unsigned long	rlim_cur;
 	unsigned long	rlim_max;
 };
+
+struct rlimit64 {
+	__u64	rlim_cur;
+	__u64	rlim_max;
+};
+
+#define INIT_RLIMFSZ   { RLIM64_INFINITY, RLIM64_INFINITY }
 
 #define	PRIO_MIN	(-20)
 #define	PRIO_MAX	20
diff -ur linux-23027p1/include/linux/sched.h linux-23027p1m1/include/linux/sched.h
--- linux-23027p1/include/linux/sched.h	Mon Nov  8 22:57:35 1999
+++ linux-23027p1m1/include/linux/sched.h	Mon Nov  8 22:58:52 1999
@@ -332,6 +332,7 @@
 	struct user_struct *user;
 /* limits */
 	struct rlimit rlim[RLIM_NLIMITS];
+	struct rlimit64 rlimfsz; /* RLIM_FSIZE -- only! */
 	unsigned short used_math;
 	char comm[16];
 /* file system info */
@@ -419,6 +420,7 @@
 /* caps */      CAP_INIT_EFF_SET,CAP_INIT_INH_SET,CAP_FULL_SET, \
 /* user */	NULL,						\
 /* rlimits */   INIT_RLIMITS, \
+/* rlimfsz */   INIT_RLIMFSZ, \
 /* math */	0, \
 /* comm */	"swapper", \
 /* fs info */	0,NULL, \
diff -ur linux-23027p1/include/linux/smb_fs.h linux-23027p1m1/include/linux/smb_fs.h
--- linux-23027p1/include/linux/smb_fs.h	Mon Nov  8 14:14:22 1999
+++ linux-23027p1m1/include/linux/smb_fs.h	Mon Nov  8 22:58:52 1999
@@ -128,8 +128,8 @@
 void smb_close_dentry(struct dentry *);
 int smb_close_fileid(struct dentry *, __u16);
 int smb_open(struct dentry *, int);
-int smb_proc_read(struct dentry *, off_t, int, char *);
-int smb_proc_write(struct dentry *, off_t, int, const char *);
+int smb_proc_read(struct dentry *, loff_t, int, char *);
+int smb_proc_write(struct dentry *, loff_t, int, const char *);
 int smb_proc_create(struct dentry *, __u16, time_t, __u16 *);
 int smb_proc_mv(struct dentry *, struct dentry *);
 int smb_proc_mkdir(struct dentry *);
@@ -139,7 +139,7 @@
 int smb_proc_getattr(struct dentry *, struct smb_fattr *);
 int smb_proc_setattr(struct dentry *, struct smb_fattr *);
 int smb_proc_settime(struct dentry *, struct smb_fattr *);
-int smb_proc_dskattr(struct super_block *, struct statfs *);
+int smb_proc_dskattr(struct super_block *, struct statvfs64 *);
 int smb_proc_reconnect(struct smb_sb_info *);
 int smb_proc_connect(struct smb_sb_info *);
 int smb_proc_disconnect(struct smb_sb_info *);
diff -ur linux-23027p1/include/linux/stat.h linux-23027p1m1/include/linux/stat.h
--- linux-23027p1/include/linux/stat.h	Mon May 25 20:32:52 1998
+++ linux-23027p1m1/include/linux/stat.h	Mon Nov  8 22:58:52 1999
@@ -3,8 +3,43 @@
 
 #ifdef __KERNEL__
 
+#include <linux/types.h>
 #include <asm/stat.h>
 
+#ifndef __ARCH_STRUCT_STAT64
+
+struct stat64 { /* Generically sized structure for all Linuxes */
+	__u64	st_dev;		/* Usually 16 or 32 bits */
+	__u64	st_rdev;
+
+	__u32	st_mode;
+	__u32	st_nlink;
+
+	__u32	st_uid;
+	__u32	st_gid;
+
+	__u64	st_ino;		/* inode is usually mere 32-bits */
+
+	__s64	st_size;	/* Large File Support */
+	__s64	st_blocks;
+	__u32	st_blksize;
+	__u32   __unused0;
+
+	long	st_atime;	/* Yup, 32 bits or 64 bits per natural */
+	long	__unused1;	/* .. size of the 'long'. */
+	long	st_mtime;
+	long	__unused2;
+	long	st_ctime;
+	long	__unused3;
+
+	__u64	st_gen;		/* Linux-FS things */
+	__u64	st_flags;
+
+	char	st_fstype[16];	/* Filesystem type name; From SysV */
+
+	__u32	__unused4[32];	/* some reserved space for possible extensions */
+};
+#endif
 #endif
 
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
diff -ur linux-23027p1/include/linux/types.h linux-23027p1m1/include/linux/types.h
--- linux-23027p1/include/linux/types.h	Mon Nov  8 14:11:09 1999
+++ linux-23027p1m1/include/linux/types.h	Mon Nov  8 22:58:52 1999
@@ -9,9 +9,11 @@
 typedef __kernel_fd_set		fd_set;
 typedef __kernel_dev_t		dev_t;
 typedef __kernel_ino_t		ino_t;
+typedef __kernel_ino64_t	ino64_t;
 typedef __kernel_mode_t		mode_t;
 typedef __kernel_nlink_t	nlink_t;
 typedef __kernel_off_t		off_t;
+typedef __kernel_off64_t	off64_t;
 typedef __kernel_pid_t		pid_t;
 typedef __kernel_uid_t		uid_t;
 typedef __kernel_gid_t		gid_t;
diff -ur linux-23027p1/include/linux/unistd.h linux-23027p1m1/include/linux/unistd.h
--- linux-23027p1/include/linux/unistd.h	Fri Oct 29 23:41:57 1999
+++ linux-23027p1m1/include/linux/unistd.h	Mon Nov  8 22:58:52 1999
@@ -8,4 +8,350 @@
  */
 #include <asm/unistd.h>
 
+
+/* ---------- KERNEL SPACE NEEDS THESE FOR  pathconf() AND sysconf()
+              THINGS AT ALL PLATFORMS  ----------------------------- */
+/* ---------- THESE ARE PICKED FROM GLIBC 2.1(pre) HEADERFILES ----- */
+/* ---------- VALUES FOR confstr ARE REMOVED ----------------------- */
+
+/* `sysconf', `pathconf', and `confstr' NAME values.  Generic version.
+   Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifdef __KERNEL__
+
+/* Values for the NAME argument to `pathconf' and `fpathconf'.  */
+enum
+  {
+    _PC_LINK_MAX	= 0,
+#define	_PC_LINK_MAX			_PC_LINK_MAX
+    _PC_MAX_CANON	= 1,
+#define	_PC_MAX_CANON			_PC_MAX_CANON
+    _PC_MAX_INPUT	= 2,
+#define	_PC_MAX_INPUT			_PC_MAX_INPUT
+    _PC_NAME_MAX	= 3,
+#define	_PC_NAME_MAX			_PC_NAME_MAX
+    _PC_PATH_MAX	= 4,
+#define	_PC_PATH_MAX			_PC_PATH_MAX
+    _PC_PIPE_BUF	= 5,
+#define	_PC_PIPE_BUF			_PC_PIPE_BUF
+    _PC_CHOWN_RESTRICTED = 6,
+#define	_PC_CHOWN_RESTRICTED		_PC_CHOWN_RESTRICTED
+    _PC_NO_TRUNC	= 7,
+#define	_PC_NO_TRUNC			_PC_NO_TRUNC
+    _PC_VDISABLE	= 8,
+#define _PC_VDISABLE			_PC_VDISABLE
+    _PC_SYNC_IO		= 9,
+#define	_PC_SYNC_IO			_PC_SYNC_IO
+    _PC_ASYNC_IO	= 10,
+#define	_PC_ASYNC_IO			_PC_ASYNC_IO
+    _PC_PRIO_IO		= 11,
+#define	_PC_PRIO_IO			_PC_PRIO_IO
+    _PC_SOCK_MAXBUF	= 12,
+#define	_PC_SOCK_MAXBUF			_PC_SOCK_MAXBUF
+    _PC_FILESIZEBITS	= 13
+#define _PC_FILESIZEBITS		_PC_FILESIZEBITS
+  };
+
+/* Values for the argument to `sysconf'.  */
+enum
+  {
+    _SC_ARG_MAX			= 0,
+#define	_SC_ARG_MAX			_SC_ARG_MAX
+    _SC_CHILD_MAX		= 1,
+#define	_SC_CHILD_MAX			_SC_CHILD_MAX
+    _SC_CLK_TCK			= 2,
+#define	_SC_CLK_TCK			_SC_CLK_TCK
+    _SC_NGROUPS_MAX		= 3,
+#define	_SC_NGROUPS_MAX			_SC_NGROUPS_MAX
+    _SC_OPEN_MAX		= 4,
+#define	_SC_OPEN_MAX			_SC_OPEN_MAX
+    _SC_STREAM_MAX		= 5,
+#define	_SC_STREAM_MAX			_SC_STREAM_MAX
+    _SC_TZNAME_MAX		= 6,
+#define	_SC_TZNAME_MAX			_SC_TZNAME_MAX
+    _SC_JOB_CONTROL		= 7,
+#define	_SC_JOB_CONTROL			_SC_JOB_CONTROL
+    _SC_SAVED_IDS		= 8,
+#define	_SC_SAVED_IDS			_SC_SAVED_IDS
+    _SC_REALTIME_SIGNALS	= 9,
+#define	_SC_REALTIME_SIGNALS		_SC_REALTIME_SIGNALS
+    _SC_PRIORITY_SCHEDULING	= 10,
+#define	_SC_PRIORITY_SCHEDULING		_SC_PRIORITY_SCHEDULING
+    _SC_TIMERS			= 11,
+#define	_SC_TIMERS			_SC_TIMERS
+    _SC_ASYNCHRONOUS_IO		= 12,
+#define	_SC_ASYNCHRONOUS_IO		_SC_ASYNCHRONOUS_IO
+    _SC_PRIORITIZED_IO		= 13,
+#define	_SC_PRIORITIZED_IO		_SC_PRIORITIZED_IO
+    _SC_SYNCHRONIZED_IO		= 14,
+#define	_SC_SYNCHRONIZED_IO		_SC_SYNCHRONIZED_IO
+    _SC_FSYNC			= 15,
+#define	_SC_FSYNC			_SC_FSYNC
+    _SC_MAPPED_FILES		= 16,
+#define	_SC_MAPPED_FILES		_SC_MAPPED_FILES
+    _SC_MEMLOCK			= 17,
+#define	_SC_MEMLOCK			_SC_MEMLOCK
+    _SC_MEMLOCK_RANGE		= 18,
+#define	_SC_MEMLOCK_RANGE		_SC_MEMLOCK_RANGE
+    _SC_MEMORY_PROTECTION	= 19,
+#define	_SC_MEMORY_PROTECTION		_SC_MEMORY_PROTECTION
+    _SC_MESSAGE_PASSING		= 20,
+#define	_SC_MESSAGE_PASSING		_SC_MESSAGE_PASSING
+    _SC_SEMAPHORES		= 21,
+#define	_SC_SEMAPHORES			_SC_SEMAPHORES
+    _SC_SHARED_MEMORY_OBJECTS	= 22,
+#define	_SC_SHARED_MEMORY_OBJECTS	_SC_SHARED_MEMORY_OBJECTS
+    _SC_AIO_LISTIO_MAX		= 23,
+#define	_SC_AIO_LISTIO_MAX		_SC_AIO_LISTIO_MAX
+    _SC_AIO_MAX			= 24,
+#define	_SC_AIO_MAX			_SC_AIO_MAX
+    _SC_AIO_PRIO_DELTA_MAX	= 25,
+#define	_SC_AIO_PRIO_DELTA_MAX		_SC_AIO_PRIO_DELTA_MAX
+    _SC_DELAYTIMER_MAX		= 26,
+#define	_SC_DELAYTIMER_MAX		_SC_DELAYTIMER_MAX
+    _SC_MQ_OPEN_MAX		= 27,
+#define	_SC_MQ_OPEN_MAX			_SC_MQ_OPEN_MAX
+    _SC_MQ_PRIO_MAX		= 28,
+#define	_SC_MQ_PRIO_MAX			_SC_MQ_PRIO_MAX
+    _SC_VERSION			= 29,
+#define	_SC_VERSION			_SC_VERSION
+    _SC_PAGESIZE		= 30,
+#define	_SC_PAGESIZE			_SC_PAGESIZE
+#define	_SC_PAGE_SIZE			_SC_PAGESIZE
+    _SC_RTSIG_MAX		= 31,
+#define	_SC_RTSIG_MAX			_SC_RTSIG_MAX
+    _SC_SEM_NSEMS_MAX		= 32,
+#define	_SC_SEM_NSEMS_MAX		_SC_SEM_NSEMS_MAX
+    _SC_SEM_VALUE_MAX		= 33,
+#define	_SC_SEM_VALUE_MAX		_SC_SEM_VALUE_MAX
+    _SC_SIGQUEUE_MAX		= 34,
+#define	_SC_SIGQUEUE_MAX		_SC_SIGQUEUE_MAX
+    _SC_TIMER_MAX		= 35,
+#define	_SC_TIMER_MAX			_SC_TIMER_MAX
+
+    /* Values for the argument to `sysconf'
+       corresponding to _POSIX2_* symbols.  */
+    _SC_BC_BASE_MAX		= 36,
+#define	_SC_BC_BASE_MAX			_SC_BC_BASE_MAX
+    _SC_BC_DIM_MAX		= 37,
+#define	_SC_BC_DIM_MAX			_SC_BC_DIM_MAX
+    _SC_BC_SCALE_MAX		= 38,
+#define	_SC_BC_SCALE_MAX		_SC_BC_SCALE_MAX
+    _SC_BC_STRING_MAX		= 39,
+#define	_SC_BC_STRING_MAX		_SC_BC_STRING_MAX
+    _SC_COLL_WEIGHTS_MAX	= 40,
+#define	_SC_COLL_WEIGHTS_MAX		_SC_COLL_WEIGHTS_MAX
+    _SC_EQUIV_CLASS_MAX		= 41,
+#define	_SC_EQUIV_CLASS_MAX		_SC_EQUIV_CLASS_MAX
+    _SC_EXPR_NEST_MAX		= 42,
+#define	_SC_EXPR_NEST_MAX		_SC_EXPR_NEST_MAX
+    _SC_LINE_MAX		= 43,
+#define	_SC_LINE_MAX			_SC_LINE_MAX
+    _SC_RE_DUP_MAX		= 44,
+#define	_SC_RE_DUP_MAX			_SC_RE_DUP_MAX
+    _SC_CHARCLASS_NAME_MAX	= 45,
+#define	_SC_CHARCLASS_NAME_MAX		_SC_CHARCLASS_NAME_MAX
+
+    _SC_2_VERSION		= 46,
+#define	_SC_2_VERSION			_SC_2_VERSION
+    _SC_2_C_BIND		= 47,
+#define	_SC_2_C_BIND			_SC_2_C_BIND
+    _SC_2_C_DEV			= 48,
+#define	_SC_2_C_DEV			_SC_2_C_DEV
+    _SC_2_FORT_DEV		= 49,
+#define	_SC_2_FORT_DEV			_SC_2_FORT_DEV
+    _SC_2_FORT_RUN		= 50,
+#define	_SC_2_FORT_RUN			_SC_2_FORT_RUN
+    _SC_2_SW_DEV		= 51,
+#define	_SC_2_SW_DEV			_SC_2_SW_DEV
+    _SC_2_LOCALEDEF		= 52,
+#define	_SC_2_LOCALEDEF			_SC_2_LOCALEDEF
+
+    _SC_PII			= 53,
+#define	_SC_PII				_SC_PII
+    _SC_PII_XTI			= 54,
+#define	_SC_PII_XTI			_SC_PII_XTI
+    _SC_PII_SOCKET		= 55,
+#define	_SC_PII_SOCKET			_SC_PII_SOCKET
+    _SC_PII_INTERNET		= 56,
+#define	_SC_PII_INTERNET		_SC_PII_INTERNET
+    _SC_PII_OSI			= 57,
+#define	_SC_PII_OSI			_SC_PII_OSI
+    _SC_POLL			= 58,
+#define	_SC_POLL			_SC_POLL
+    _SC_SELECT			= 59,
+#define	_SC_SELECT			_SC_SELECT
+    _SC_UIO_MAXIOV		= 60,
+#define	_SC_UIO_MAXIOV			_SC_UIO_MAXIOV
+    _SC_PII_INTERNET_STREAM	= 61,
+#define	_SC_PII_INTERNET_STREAM		_SC_PII_INTERNET_STREAM
+    _SC_PII_INTERNET_DGRAM	= 62,
+#define	_SC_PII_INTERNET_DGRAM		_SC_PII_INTERNET_DGRAM
+    _SC_PII_OSI_COTS		= 63,
+#define	_SC_PII_OSI_COTS		_SC_PII_OSI_COTS
+    _SC_PII_OSI_CLTS		= 64,
+#define	_SC_PII_OSI_CLTS		_SC_PII_OSI_CLTS
+    _SC_PII_OSI_M		= 65,
+#define	_SC_PII_OSI_M			_SC_PII_OSI_M
+    _SC_T_IOV_MAX		= 66,
+#define	_SC_T_IOV_MAX			_SC_T_IOV_MAX
+
+    /* Values according to POSIX 1003.1c (POSIX threads).  */
+    _SC_THREADS			= 67,
+#define	_SC_THREADS			_SC_THREADS
+    _SC_THREAD_SAFE_FUNCTIONS	= 68,
+#define _SC_THREAD_SAFE_FUNCTIONS	_SC_THREAD_SAFE_FUNCTIONS
+    _SC_GETGR_R_SIZE_MAX	= 69,
+#define	_SC_GETGR_R_SIZE_MAX		_SC_GETGR_R_SIZE_MAX
+    _SC_GETPW_R_SIZE_MAX	= 70,
+#define	_SC_GETPW_R_SIZE_MAX		_SC_GETPW_R_SIZE_MAX
+    _SC_LOGIN_NAME_MAX		= 71,
+#define	_SC_LOGIN_NAME_MAX		_SC_LOGIN_NAME_MAX
+    _SC_TTY_NAME_MAX		= 72,
+#define	_SC_TTY_NAME_MAX		_SC_TTY_NAME_MAX
+    _SC_THREAD_DESTRUCTOR_ITERATIONS		= 73,
+#define	_SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS
+    _SC_THREAD_KEYS_MAX		= 74,
+#define	_SC_THREAD_KEYS_MAX		_SC_THREAD_KEYS_MAX
+    _SC_THREAD_STACK_MIN	= 75,
+#define	_SC_THREAD_STACK_MIN		_SC_THREAD_STACK_MIN
+    _SC_THREAD_THREADS_MAX	= 76,
+#define	_SC_THREAD_THREADS_MAX		_SC_THREAD_THREADS_MAX
+    _SC_THREAD_ATTR_STACKADDR	= 77,
+#define	_SC_THREAD_ATTR_STACKADDR	_SC_THREAD_ATTR_STACKADDR
+    _SC_THREAD_ATTR_STACKSIZE	= 78,
+#define	_SC_THREAD_ATTR_STACKSIZE	_SC_THREAD_ATTR_STACKSIZE
+    _SC_THREAD_PRIORITY_SCHEDULING = 79,
+#define	_SC_THREAD_PRIORITY_SCHEDULING	_SC_THREAD_PRIORITY_SCHEDULING
+    _SC_THREAD_PRIO_INHERIT	= 80,
+#define	_SC_THREAD_PRIO_INHERIT		_SC_THREAD_PRIO_INHERIT
+    _SC_THREAD_PRIO_PROTECT	= 81,
+#define	_SC_THREAD_PRIO_PROTECT		_SC_THREAD_PRIO_PROTECT
+    _SC_THREAD_PROCESS_SHARED	= 82,
+#define	_SC_THREAD_PROCESS_SHARED	_SC_THREAD_PROCESS_SHARED
+
+    _SC_NPROCESSORS_CONF	= 83,
+#define _SC_NPROCESSORS_CONF		_SC_NPROCESSORS_CONF
+    _SC_NPROCESSORS_ONLN	= 84,
+#define _SC_NPROCESSORS_ONLN		_SC_NPROCESSORS_ONLN
+    _SC_PHYS_PAGES		= 85,
+#define _SC_PHYS_PAGES			_SC_PHYS_PAGES
+    _SC_AVPHYS_PAGES		= 86,
+#define _SC_AVPHYS_PAGES		_SC_AVPHYS_PAGES
+    _SC_ATEXIT_MAX		= 87,
+#define _SC_ATEXIT_MAX			_SC_ATEXIT_MAX
+    _SC_PASS_MAX		= 88,
+#define _SC_PASS_MAX			_SC_PASS_MAX
+
+    _SC_XOPEN_VERSION		= 89,
+#define _SC_XOPEN_VERSION		_SC_XOPEN_VERSION
+    _SC_XOPEN_XCU_VERSION	= 90,
+#define _SC_XOPEN_XCU_VERSION		_SC_XOPEN_XCU_VERSION
+    _SC_XOPEN_UNIX		= 91,
+#define _SC_XOPEN_UNIX			_SC_XOPEN_UNIX
+    _SC_XOPEN_CRYPT		= 92,
+#define _SC_XOPEN_CRYPT			_SC_XOPEN_CRYPT
+    _SC_XOPEN_ENH_I18N		= 93,
+#define _SC_XOPEN_ENH_I18N		_SC_XOPEN_ENH_I18N
+    _SC_XOPEN_SHM		= 94,
+#define _SC_XOPEN_SHM			_SC_XOPEN_SHM
+
+    _SC_2_CHAR_TERM		= 95,
+#define _SC_2_CHAR_TERM			_SC_2_CHAR_TERM
+    _SC_2_C_VERSION		= 96,
+#define _SC_2_C_VERSION			_SC_2_C_VERSION
+    _SC_2_UPE			= 97,
+#define _SC_2_UPE			_SC_2_UPE
+
+    _SC_XOPEN_XPG2		= 98,
+#define _SC_XOPEN_XPG2			_SC_XOPEN_XPG2
+    _SC_XOPEN_XPG3		= 99,
+#define _SC_XOPEN_XPG3			_SC_XOPEN_XPG3
+    _SC_XOPEN_XPG4		= 100,
+#define _SC_XOPEN_XPG4			_SC_XOPEN_XPG4
+
+    _SC_CHAR_BIT		= 101,
+#define	_SC_CHAR_BIT			_SC_CHAR_BIT
+    _SC_CHAR_MAX		= 102,
+#define	_SC_CHAR_MAX			_SC_CHAR_MAX
+    _SC_CHAR_MIN		= 103,
+#define	_SC_CHAR_MIN			_SC_CHAR_MIN
+    _SC_INT_MAX			= 104,
+#define	_SC_INT_MAX			_SC_INT_MAX
+    _SC_INT_MIN			= 105,
+#define	_SC_INT_MIN			_SC_INT_MIN
+    _SC_LONG_BIT		= 106,
+#define	_SC_LONG_BIT			_SC_LONG_BIT
+    _SC_WORD_BIT		= 107,
+#define	_SC_WORD_BIT			_SC_WORD_BIT
+    _SC_MB_LEN_MAX		= 108,
+#define	_SC_MB_LEN_MAX			_SC_MB_LEN_MAX
+    _SC_NZERO			= 109,
+#define	_SC_NZERO			_SC_NZERO
+    _SC_SSIZE_MAX		= 110,
+#define	_SC_SSIZE_MAX			_SC_SSIZE_MAX
+    _SC_SCHAR_MAX		= 111,
+#define	_SC_SCHAR_MAX			_SC_SCHAR_MAX
+    _SC_SCHAR_MIN		= 112,
+#define	_SC_SCHAR_MIN			_SC_SCHAR_MIN
+    _SC_SHRT_MAX		= 113,
+#define	_SC_SHRT_MAX			_SC_SHRT_MAX
+    _SC_SHRT_MIN		= 114,
+#define	_SC_SHRT_MIN			_SC_SHRT_MIN
+    _SC_UCHAR_MAX		= 115,
+#define	_SC_UCHAR_MAX			_SC_UCHAR_MAX
+    _SC_UINT_MAX		= 116,
+#define	_SC_UINT_MAX			_SC_UINT_MAX
+    _SC_ULONG_MAX		= 117,
+#define	_SC_ULONG_MAX			_SC_ULONG_MAX
+    _SC_USHRT_MAX		= 118,
+#define	_SC_USHRT_MAX			_SC_USHRT_MAX
+
+    _SC_NL_ARGMAX		= 119,
+#define	_SC_NL_ARGMAX			_SC_NL_ARGMAX
+    _SC_NL_LANGMAX		= 120,
+#define	_SC_NL_LANGMAX			_SC_NL_LANGMAX
+    _SC_NL_MSGMAX		= 121,
+#define	_SC_NL_MSGMAX			_SC_NL_MSGMAX
+    _SC_NL_NMAX			= 122,
+#define	_SC_NL_NMAX			_SC_NL_NMAX
+    _SC_NL_SETMAX		= 123,
+#define	_SC_NL_SETMAX			_SC_NL_SETMAX
+    _SC_NL_TEXTMAX		= 124,
+#define	_SC_NL_TEXTMAX			_SC_NL_TEXTMAX
+
+    _SC_XBS5_ILP32_OFF32	= 125,
+#define _SC_XBS5_ILP32_OFF32		_SC_XBS5_ILP32_OFF32
+    _SC_XBS5_ILP32_OFFBIG	= 126,
+#define _SC_XBS5_ILP32_OFFBIG		_SC_XBS5_ILP32_OFFBIG
+    _SC_XBS5_LP64_OFF64		= 127,
+#define _SC_XBS5_LP64_OFF64		_SC_XBS5_LP64_OFF64
+    _SC_XBS5_LPBIG_OFFBIG	= 128,
+#define _SC_XBS5_LPBIG_OFFBIG		_SC_XBS5_LPBIG_OFFBIG
+
+    _SC_XOPEN_LEGACY		= 129,
+#define _SC_XOPEN_LEGACY		_SC_XOPEN_LEGACY
+    _SC_XOPEN_REALTIME		= 130,
+#define _SC_XOPEN_REALTIME		_SC_XOPEN_REALTIME
+    _SC_XOPEN_REALTIME_THREADS	= 131,
+#define _SC_XOPEN_REALTIME_THREADS	_SC_XOPEN_REALTIME_THREADS
+  };
+#endif
+
 #endif /* _LINUX_UNISTD_H_ */
diff -ur linux-23027p1/kernel/acct.c linux-23027p1m1/kernel/acct.c
--- linux-23027p1/kernel/acct.c	Mon Aug 23 21:15:53 1999
+++ linux-23027p1m1/kernel/acct.c	Mon Nov  8 22:58:52 1999
@@ -88,8 +88,7 @@
  */
 static int check_free_space(struct file *file)
 {
-	mm_segment_t fs;
-	struct statfs sbuf;
+	struct statvfs64 sbuf;
 	struct super_block *sb;
 	int res = acct_active;
 	int act;
@@ -98,18 +97,15 @@
 		return res;
 
 	sb = file->f_dentry->d_inode->i_sb;
-	if (!sb->s_op || !sb->s_op->statfs)
+	if (!sb->s_op || !sb->s_op->statvfs)
 		return res;
 
-	fs = get_fs();
-	set_fs(KERNEL_DS);
 	/* May block */
-	sb->s_op->statfs(sb, &sbuf, sizeof(struct statfs));
-	set_fs(fs);
+	sb->s_op->statvfs(sb, &sbuf);
 
-	if (sbuf.f_bavail <= SUSPEND * sbuf.f_blocks / 100)
+	if (sbuf.f_bavail <= (u_long)(SUSPEND * sbuf.f_blocks) / 100)
 		act = -1;
-	else if (sbuf.f_bavail >= RESUME * sbuf.f_blocks / 100)
+	else if (sbuf.f_bavail >= (u_long)(RESUME * sbuf.f_blocks) / 100)
 		act = 1;
 	else
 		act = 0;
diff -ur linux-23027p1/kernel/sys.c linux-23027p1m1/kernel/sys.c
--- linux-23027p1/kernel/sys.c	Fri Oct 29 23:19:49 1999
+++ linux-23027p1m1/kernel/sys.c	Mon Nov  8 22:58:52 1999
@@ -12,6 +12,7 @@
 #include <linux/reboot.h>
 #include <linux/prctl.h>
 #include <linux/init.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -882,11 +883,44 @@
 
 asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim)
 {
+	struct rlimit rl;
+
 	if (resource >= RLIM_NLIMITS)
 		return -EINVAL;
-	else
-		return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim))
-			? -EFAULT : 0;
+
+	rl = current->rlim[resource];
+	if (resource == RLIMIT_FSIZE) {
+	  rl.rlim_cur = current->rlimfsz.rlim_cur;
+	  if (current->rlimfsz.rlim_cur > RLIM_INFINITY)
+	    rl.rlim_cur = RLIM_INFINITY;
+	  rl.rlim_max = current->rlimfsz.rlim_max;
+	  if (current->rlimfsz.rlim_max > RLIM_INFINITY)
+	    rl.rlim_max = RLIM_INFINITY;
+
+	  /* XX: RLIM_SAVED_MAX ? RLIM_SAVED_CUR ? (See Large-File-Summit) */
+	}
+	return (copy_to_user(rlim, &rl, sizeof(*rlim)) ? -EFAULT : 0);
+}
+
+asmlinkage long sys_getrlimit64(unsigned int resource, struct rlimit64 *rlim)
+{
+	struct rlimit64 rlim64;
+
+	if (resource >= RLIM_NLIMITS)
+		return -EINVAL;
+
+	if (resource == RLIMIT_FSIZE)
+	  rlim64 = current->rlimfsz;
+	else {
+	  rlim64.rlim_cur = current->rlim[resource].rlim_cur;
+	  rlim64.rlim_max = current->rlim[resource].rlim_max;
+	  if (rlim64.rlim_cur == RLIM_INFINITY)
+	    rlim64.rlim_cur = RLIM64_INFINITY;
+	  if (rlim64.rlim_max == RLIM_INFINITY)
+	    rlim64.rlim_max = RLIM64_INFINITY;
+	  /* XX: RLIM_SAVED_MAX ? RLIM_SAVED_CUR ? (See Large-File-Summit) */
+	}
+	return (copy_to_user(rlim, &rlim64, sizeof(*rlim)) ? -EFAULT : 0);
 }
 
 /*
@@ -899,7 +933,18 @@
 	if (resource >= RLIM_NLIMITS)
 		return -EINVAL;
 
-	memcpy(&x, current->rlim + resource, sizeof(*rlim));
+	x = current->rlim[resource];
+	if (resource == RLIMIT_FSIZE) {
+	  x.rlim_cur = current->rlimfsz.rlim_cur;
+	  if (current->rlimfsz.rlim_cur > RLIM_INFINITY)
+	    x.rlim_cur = RLIM_INFINITY;
+	  x.rlim_max = current->rlimfsz.rlim_max;
+	  if (current->rlimfsz.rlim_max > RLIM_INFINITY)
+	    x.rlim_max = RLIM_INFINITY;
+
+	  /* XX: RLIM_SAVED_MAX ? RLIM_SAVED_CUR ? (See Large-File-Summit) */
+	}
+
 	if(x.rlim_cur > 0x7FFFFFFF)
 		x.rlim_cur = 0x7FFFFFFF;
 	if(x.rlim_max > 0x7FFFFFFF)
@@ -916,8 +961,15 @@
 		return -EINVAL;
 	if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
 		return -EFAULT;
-	if (new_rlim.rlim_cur < 0 || new_rlim.rlim_max < 0)
-		return -EINVAL;
+
+#if BITS_PER_LONG < 64
+	/* compability with old RLIM_INFINITY value .. */
+	if (new_rlim.rlim_cur == 0x7fffffffUL)
+	  new_rlim.rlim_cur = RLIM_INFINITY;
+	if (new_rlim.rlim_max == 0x7fffffffUL)
+	  new_rlim.rlim_max = RLIM_INFINITY;
+#endif
+
 	old_rlim = current->rlim + resource;
 	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
 	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
@@ -927,10 +979,62 @@
 		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
 			return -EPERM;
 	}
+	if (resource == RLIMIT_FSIZE) {
+		if (new_rlim.rlim_cur == RLIM_INFINITY) {
+			current->rlimfsz.rlim_cur = RLIM64_INFINITY;
+		}
+		if (new_rlim.rlim_max == RLIM_INFINITY) {
+			current->rlimfsz.rlim_max = RLIM64_INFINITY;
+		}
+	}
 	*old_rlim = new_rlim;
 	return 0;
 }
 
+asmlinkage long sys_setrlimit64(unsigned int resource, struct rlimit64 *rlim)
+{
+	struct rlimit64 new_rlim;
+	struct rlimit  *old_rlim;
+
+	if (resource >= RLIM_NLIMITS)
+		return -EINVAL;
+	if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
+		return -EFAULT;
+	old_rlim = &current->rlim[resource];
+	
+
+	if (new_rlim.rlim_cur > RLIM_INFINITY && resource != RLIMIT_FSIZE)
+	  new_rlim.rlim_cur = RLIM_INFINITY;
+	if (new_rlim.rlim_max > RLIM_INFINITY && resource != RLIMIT_FSIZE)
+	  new_rlim.rlim_max = RLIM_INFINITY;
+
+	if (resource == RLIMIT_FSIZE) {
+		if (((new_rlim.rlim_cur > current->rlimfsz.rlim_max) ||
+		     (new_rlim.rlim_max > current->rlimfsz.rlim_max)) &&
+		    !capable(CAP_SYS_RESOURCE))
+			return -EPERM;
+	} else
+		if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
+		     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
+		    !capable(CAP_SYS_RESOURCE))
+			return -EPERM;
+	if (resource == RLIMIT_NOFILE) {
+		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
+			return -EPERM;
+	}
+	if (resource == RLIMIT_FSIZE) {
+		current->rlimfsz = new_rlim;
+
+		if (new_rlim.rlim_cur > RLIM_INFINITY)
+		  new_rlim.rlim_cur = RLIM_INFINITY;
+		if (new_rlim.rlim_max > RLIM_INFINITY)
+		  new_rlim.rlim_max = RLIM_INFINITY;
+	}
+	old_rlim->rlim_cur = new_rlim.rlim_cur;
+	old_rlim->rlim_max = new_rlim.rlim_max;
+	return 0;
+}
+
 /*
  * It would make sense to put struct rusage in the task_struct,
  * except that would make the task_struct be *really big*.  After
@@ -948,7 +1052,7 @@
  *
  * FIXME! Get the fault counts properly!
  */
-int getrusage(struct task_struct *p, int who, struct rusage *ru)
+long getrusage(struct task_struct *p, int who, struct rusage *ru)
 {
 	struct rusage r;
 
@@ -1034,3 +1138,70 @@
 	return error;
 }
 
+
+/*
+ * POSIX sysconf() things
+ *
+ * There are things for which the existence of this makes
+ * a lot of sense; Adding new facilities to the system allows
+ * things like libc to detect availability of those way easier
+ * thru  sysconf(),  than by any other means.
+ * Mostly these are for other than POSIX.1 things, e.g. for
+ * POSIX.1b, POSIX.1b (aka REAL TIME and THREADS, respectively)
+ *
+ * sysconf() returns -1 for all those option values it does
+ * not recognize.  *Never* shall it set errno!
+ *
+ * Returning ``-1'' without errno is indicated by returning ``-INT_MAX''
+ */
+
+asmlinkage long sys_sysconf(int option)
+{
+	switch(option) {
+#if 0 /* Drepper thinking: These shouldn't be in kernel */
+	case _SC_JOB_CONTROL:		/* POSIX.1 */
+		return 1;
+	case _SC_SAVED_IDS:
+		return -INT_MAX; /* FIXME! What the value *should* be ? */
+	case _SC_VERSION:
+		return -INT_MAX; /* FIXME! What _POSIX_VERSION we have
+				   in the kernel proper ? */
+#endif
+	case _SC_ARG_MAX:
+		return ARG_MAX;
+
+	case _SC_CHILD_MAX:
+		return -INT_MAX;
+
+	case _SC_CLK_TCK:
+		return HZ;
+
+	case _SC_NGROUPS_MAX:
+		return NGROUPS_MAX;
+
+	case _SC_OPEN_MAX:	/* POSIX.1  Max simultaneous files   */
+	case _SC_STREAM_MAX:	/* POSIX.1: Max simultaneous streams */
+		return NR_OPEN; /* The upper hard limit; Normally something
+				   like 1024, but insanely large file arrays
+				   can also be supported in the system giving
+				   this here 1024*1024 (yep, MILLION!) */
+
+#if 0	/* Library thing */
+	case _SC_TZNAME_MAX:
+		return -INT_MAX;
+#endif
+#if 0 /* Drepper thinking: Most of these are library things, and don't
+	 belong to kernel..  Must sort them out someday.. */
+	case _SC_ASYNCHRONOUS_IO:	/* POSIX.4 */
+	case _SC_MAPPED_FILES:
+	case _SC_MEMLOCK:
+	case _SC_MEMLOCK_RANGE:
+	case _SC_MEMORY_PROTECTION:
+		/* ... more! ... */
+		break;
+#endif
+	default:	/* Anything not considered in kernel -> EINVAL */
+		break;
+	}
+	return -EINVAL;
+}
diff -ur linux-23027p1/lib/vsprintf.c linux-23027p1m1/lib/vsprintf.c
--- linux-23027p1/lib/vsprintf.c	Sun Jul 25 02:42:01 1999
+++ linux-23027p1m1/lib/vsprintf.c	Mon Nov  8 22:58:52 1999
@@ -7,6 +7,9 @@
 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
 /*
  * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ *
+ * Matti Aarnio added '%L' support
+ *
  */
 
 #include <stdarg.h>
@@ -67,10 +70,107 @@
 #define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
 
 #define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
+  int __res = ((unsigned long) n) % (unsigned) base; \
+  n = ((unsigned long) n) / (unsigned) base; \
+  __res; })
+
+#if BITS_PER_LONG < 64
+
+/* Note: do_ldiv assumes that unsigned long long is a 64 bit long
+ * and unsigned long is at least a 32 bits long.
+ */
+
+#define do_ldiv(n, base) \
+({ \
+	unsigned long long value = n; \
+	unsigned long long leftover; \
+	unsigned long temp; \
+	unsigned long result_div1, result_div2, result_div3, result_mod; \
+\
+	temp = value >> 32; \
+	result_div1 = temp/(base); \
+	result_mod = temp%(base); \
+\
+	temp = (result_mod << 24) | ((value >> 8) & 0xFFFFFF); \
+	result_div2 = temp/(base); \
+	result_mod = temp%(base); \
+\
+	temp = (result_mod << 8) | (value & 0xFF); \
+	result_div3 = temp/(base); \
+	result_mod = temp%(base);\
+\
+	leftover = ((unsigned long long)result_div1 << 32) | \
+		((unsigned long long)result_div2 << 8) | (result_div3); \
+\
+	n = leftover; \
+	result_mod; \
+})
+
+
+static char * lnumber(char * str, long long num, int base, int size,
+		      int precision, int type)
+{
+	char c,sign,tmp[66];
+	const char *digits="0123456789abcdef";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEF";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++]='0';
+	else while (num != 0)
+		tmp[i++] = digits[do_ldiv(num,base)];
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type&(ZEROPAD+LEFT)))
+		while(size-->0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base==16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+#endif
+
 
 static char * number(char * str, long num, int base, int size, int precision
 	,int type)
@@ -208,8 +308,11 @@
 
 		/* get the conversion qualifier */
 		qualifier = -1;
-		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='z') {
-			qualifier = *fmt;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'z') {
+			if (*fmt == 'l' && qualifier == 'l')
+				qualifier = 'L';
+			else
+				qualifier = *fmt;
 			++fmt;
 		}
 
@@ -295,7 +398,22 @@
 				--fmt;
 			continue;
 		}
-		if (qualifier == 'l')
+
+		if (qualifier == 'L') {
+#if BITS_PER_LONG < 64
+		/* 64-bit printout in 32-bit systems !!
+		   Needed at some point for 64-bit file offsets and
+		   mmap() reporting functions. */
+
+			unsigned long long lnum;
+			lnum = va_arg(args, unsigned long long);
+			str = lnumber(str, lnum, base, field_width,
+				      precision, flags);
+			continue;
+#else
+			num = va_arg(args, unsigned long); /* 64-bit longs..*/
+#endif
+		} else if (qualifier == 'l')
 			num = va_arg(args, unsigned long);
 		else if (qualifier == 'z')
 			num = va_arg(args, size_t);
diff -ur linux-23027p1/mm/filemap.c linux-23027p1m1/mm/filemap.c
--- linux-23027p1/mm/filemap.c	Sat Nov  6 02:16:48 1999
+++ linux-23027p1m1/mm/filemap.c	Mon Nov  8 22:58:52 1999
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
+#include <linux/unistd.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -122,13 +123,14 @@
  * Truncate the page cache at a set offset, removing the pages
  * that are beyond that offset (and zeroing out partial pages).
  */
-void truncate_inode_pages(struct inode * inode, unsigned long start)
+void truncate_inode_pages(struct inode * inode, loff_t lstart)
 {
 	struct list_head *head, *curr;
 	struct page * page;
-	unsigned partial = start & (PAGE_CACHE_SIZE - 1);
+	unsigned partial = lstart & (PAGE_CACHE_SIZE - 1);
+	unsigned long start;
 
-	start = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	start = (lstart + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
 repeat:
 	head = &inode->i_data.pages;
@@ -412,7 +414,7 @@
 	return error;
 }
 
-static int do_buffer_fdatasync(struct inode *inode, unsigned long start, unsigned long end, int (*fn)(struct page *))
+static int do_buffer_fdatasync(struct inode *inode, unsigned long startidx, unsigned long endidx, int (*fn)(struct page *))
 {
 	struct list_head *head, *curr;
 	struct page *page;
@@ -427,9 +429,9 @@
 		curr = curr->next;
 		if (!page->buffers)
 			continue;
-		if (page->index >= end)
+		if (page->index >= endidx)
 			continue;
-		if (page->index < start)
+		if (page->index < startidx)
 			continue;
 
 		get_page(page);
@@ -454,7 +456,7 @@
  * Two-stage data sync: first start the IO, then go back and
  * collect the information..
  */
-int generic_buffer_fdatasync(struct inode *inode, unsigned long start, unsigned long end)
+int generic_buffer_fdatasync(struct inode *inode, loff_t start, loff_t end)
 {
 	unsigned long start_idx = start >> PAGE_CACHE_SHIFT;
 	unsigned long end_idx = (end + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
@@ -550,19 +552,19 @@
 
 /*
  * Read in an entire cluster at once.  A cluster is usually a 64k-
- * aligned block that includes the address requested in "offset."
+ * aligned block that includes the address requested in "index."
  */
-static int read_cluster_nonblocking(struct file * file, unsigned long offset)
+static int read_cluster_nonblocking(struct file * file, unsigned long index)
 {
 	int error = 0;
 	unsigned long filesize = (file->f_dentry->d_inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	unsigned long pages = CLUSTER_PAGES;
 
-	offset = CLUSTER_OFFSET(offset);
-	while ((pages-- > 0) && (offset < filesize)) {
-		error = page_cache_read(file, offset);
+	index = CLUSTER_OFFSET(index);
+	while ((pages-- > 0) && (index < filesize)) {
+		error = page_cache_read(file, index);
 		if (error >= 0)
-			offset ++;
+			index ++;
 		else
 			break;
 	}
@@ -776,8 +778,7 @@
  * Read-ahead context:
  * -------------------
  * The read ahead context fields of the "struct file" are the following:
- * - f_raend : position of the first byte after the last page we tried to
- *	       read ahead.
+ * - f_raend : index of the last page+1 we tried to read ahead.
  * - f_ramax : current read-ahead maximum size.
  * - f_ralen : length of the current IO read block we tried to read-ahead.
  * - f_rawin : length of the current read-ahead window.
@@ -1166,11 +1167,23 @@
 ssize_t generic_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
 {
 	ssize_t retval;
+	struct inode *inode = filp->f_dentry->d_inode;
 
 	retval = -EFAULT;
 	if (access_ok(VERIFY_WRITE, buf, count)) {
 		retval = 0;
 
+		/* L-F-S spec 2.2.1.25: */
+		if (count && !(filp->f_flags & O_LARGEFILE) &&
+		    S_ISREG(inode->i_mode) &&
+		    (*ppos < inode->i_size) &&
+		    !off_t_presentable(*ppos + count)) {
+			if (*ppos >= LONG_MAX) /* pos@LONG_MAX forbidden! */
+			  return -EOVERFLOW;
+			/* Read only until end of allowed region */
+			count = LONG_MAX - *ppos;
+		}
+
 		if (count) {
 			read_descriptor_t desc;
 
@@ -1213,6 +1226,10 @@
 	return written;
 }
 
+/*
+ *  sys_sendfile() isn't LARGEFILE compatible in all systems
+ */
+
 asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
 {
 	ssize_t retval;
@@ -1261,12 +1278,14 @@
 	if (count) {
 		read_descriptor_t desc;
 		loff_t pos = 0, *ppos;
+		off_t posp;
 
 		retval = -EFAULT;
 		ppos = &in_file->f_pos;
 		if (offset) {
-			if (get_user(pos, offset))
+			if (get_user(posp, offset))
 				goto fput_out;
+			pos = posp;
 			ppos = &pos;
 		}
 
@@ -1279,8 +1298,9 @@
 		retval = desc.written;
 		if (!retval)
 			retval = desc.error;
+		posp = pos;
 		if (offset)
-			put_user(pos, offset);
+			put_user(posp, offset);
 	}
 
 fput_out:
@@ -1434,19 +1454,18 @@
  * if the disk is full.
  */
 static inline int do_write_page(struct inode * inode, struct file * file,
-	struct page * page, unsigned long offset)
+	struct page * page, unsigned long pgindex)
 {
 	int retval;
-	unsigned long size;
 	int (*writepage) (struct file *, struct page *);
 
-	size = (offset << PAGE_CACHE_SHIFT) + PAGE_CACHE_SIZE;
 	/* refuse to extend file size.. */
 	if (S_ISREG(inode->i_mode)) {
-		if (size > inode->i_size)
-			size = inode->i_size;
 		/* Ho humm.. We should have tested for this earlier */
-		if (size < offset)
+		unsigned long pgsize;
+		pgsize = inode->i_size >> PAGE_CACHE_SHIFT;
+		/* This is a matter of full cluster blocks */
+		if (pgindex >= pgsize)
 			return -EIO;
 	}
 	retval = -EIO;
@@ -1460,7 +1479,7 @@
 }
 
 static int filemap_write_page(struct file *file,
-			      unsigned long offset,
+			      unsigned long pgindex,
 			      struct page * page,
 			      int wait)
 {
@@ -1477,7 +1496,7 @@
 	 * vma/file is guaranteed to exist in the unmap/sync cases because
 	 * mmap_sem is held.
 	 */
-	result = do_write_page(inode, file, page, offset);
+	result = do_write_page(inode, file, page, pgindex);
 	return result;
 }
 
@@ -1792,7 +1811,7 @@
 {
 	struct dentry	*dentry = file->f_dentry; 
 	struct inode	*inode = dentry->d_inode; 
-	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	loff_t		limit = current->rlimfsz.rlim_cur;
 	loff_t		pos = *ppos;
 	struct page	*page, **hash, *cached_page;
 	unsigned long	written;
@@ -1820,16 +1839,59 @@
 	 * Check whether we've reached the file size limit.
 	 */
 	err = -EFBIG;
-	if (limit != RLIM_INFINITY) {
-		if (pos >= limit) {
-			send_sig(SIGXFSZ, current, 0);
-			goto out;
-		}
-		if (count > limit - pos) {
-			send_sig(SIGXFSZ, current, 0);
-			count = limit - pos;
-		}
+	if (pos >= limit) {
+// printk(" generic_file_write() EFBIG: pos=%Lx limit=%Lx\n",pos,limit);
+		send_sig(SIGXFSZ, current, 0);
+		goto out;
+	}
+	if (count > limit - pos) {
+		/* send_sig(SIGXFSZ, current, 0); */
+		count = limit - pos;
 	}
+
+
+	/* REGULAR files have Large File Summit rules */
+
+	if (S_ISREG(inode->i_mode)) {
+
+	  const loff_t lim2G = 0x7FFFFFFFLL;
+
+	  if (!inode->i_op->pathconf ||
+	      inode->i_op->pathconf(inode,_PC_FILESIZEBITS) <= 32) {
+	    /* Hmm... 31 = 2G, 32 = 4G ?? */
+
+	    /* L-F-S: Must limit down to 2G! */
+
+	    if ((pos+count) > lim2G) {
+	      if (pos >= lim2G) { /* over 2G-1 */
+		/* Fails completely! Err = -EFBIG */
+		send_sig(SIGXFSZ, current, 0);
+		goto out;
+	      } else { /* At most 2G-1 */
+		count = lim2G-pos;
+	      }
+	    }
+	  }
+
+#if BITS_PER_LONG < 64 /* Large File Summit has meaning ! */
+	  else {
+	    /* This filesystem *can* support Large Files */
+	    if (!(file->f_flags & O_LARGEFILE)) {
+	      /* Not opened as Large File */
+	      if ((pos+count) > lim2G) {
+		if (pos >= lim2G) { /* over 2G-1 */
+		  /* Fails completely! Err = -EFBIG */
+		  send_sig(SIGXFSZ, current, 0);
+		  goto out;
+		} else { /* At most 2G-1 */
+		  count = lim2G-pos;
+		}
+	      }
+	    }
+	  }
+#endif
+	} /* ... was REGULAR file */
+
 
 	status  = 0;
 
diff -ur linux-23027p1/mm/memory.c linux-23027p1m1/mm/memory.c
--- linux-23027p1/mm/memory.c	Fri Nov  5 05:36:33 1999
+++ linux-23027p1m1/mm/memory.c	Mon Nov  8 22:58:52 1999
@@ -885,7 +885,7 @@
  * between the file and the memory map for a potential last
  * incomplete page.  Ugly, but necessary.
  */
-void vmtruncate(struct inode * inode, unsigned long offset)
+void vmtruncate(struct inode * inode, loff_t offset)
 {
 	unsigned long partial, pgoff;
 	struct vm_area_struct * mpnt;
diff -ur linux-23027p1/mm/mmap.c linux-23027p1m1/mm/mmap.c
--- linux-23027p1/mm/mmap.c	Thu Oct 28 23:03:38 1999
+++ linux-23027p1m1/mm/mmap.c	Mon Nov  8 22:58:52 1999
@@ -161,11 +161,12 @@
 }
 
 unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags, unsigned long off)
+	unsigned long prot, unsigned long flags, loff_t loff)
 {
 	struct mm_struct * mm = current->mm;
 	struct vm_area_struct * vma;
 	int error;
+	unsigned long off;
 
 	if (file && (!file->f_op || !file->f_op->mmap))
 		return -ENODEV;
@@ -176,14 +177,14 @@
 	if (len > TASK_SIZE || addr > TASK_SIZE-len)
 		return -EINVAL;
 
-	if (off & ~PAGE_MASK)
+	if (loff & ~PAGE_MASK)
 		return -EINVAL;
 
-	/* offset overflow? */
-	if (off + len < off)
+	/* offset overflow? (propably not..) */
+	if (loff + len < loff)
 		return -EINVAL;
 
-	off = off >> PAGE_SHIFT;
+	off = loff >> PAGE_SHIFT;
 
 	/* Too many mappings? */
 	if (mm->map_count > MAX_MAP_COUNT)
diff -ur linux-23027p1/mm/vmscan.c linux-23027p1m1/mm/vmscan.c
--- linux-23027p1/mm/vmscan.c	Sat Oct 30 02:45:32 1999
+++ linux-23027p1m1/mm/vmscan.c	Mon Nov  8 22:58:52 1999
@@ -19,6 +19,8 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/file.h>
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
 
 #include <asm/pgtable.h>
 
diff -ur linux-23027p1/net/khttpd/datasending.c linux-23027p1m1/net/khttpd/datasending.c
--- linux-23027p1/net/khttpd/datasending.c	Thu Aug 26 19:41:36 1999
+++ linux-23027p1m1/net/khttpd/datasending.c	Mon Nov  8 22:58:53 1999
@@ -55,7 +55,11 @@
 It sends the data to the socket indicated by desc->buf.
 
 */
-static int sock_send_actor(read_descriptor_t * desc, const char *area, unsigned long size)
+
+// FIXME: usage of these parameters is not corrected in code below,
+// FIXME: while call parameters are now modern...
+
+static int sock_send_actor(read_descriptor_t * desc, struct page * page, unsigned long offset, unsigned long size)
 {
 	int written;
 	unsigned long count = desc->count;
@@ -63,7 +67,7 @@
 
 	if (size > count)
 		size = count;
-	written = SendBuffer_async(sock,(char *)area,size);
+	written = SendBuffer_async(sock, page, size);
 
 	if (written < 0) {
 		desc->error = written;
diff -ur linux-23027p1/net/khttpd/main.c linux-23027p1m1/net/khttpd/main.c
--- linux-23027p1/net/khttpd/main.c	Tue Aug 31 21:30:48 1999
+++ linux-23027p1m1/net/khttpd/main.c	Mon Nov  8 22:58:53 1999
@@ -58,7 +58,7 @@
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/smp_lock.h>
-#include <asm/unistd.h>
+#include <linux/unistd.h>
 
 #include "structure.h"
 #include "prototypes.h"
