[OpenAFS-devel] Re: OpenAFS on RedHat 2.2.19-6.2.7enterprise kernel: solution!

Alf Wachsmann alfw@SLAC.Stanford.EDU
Thu, 13 Sep 2001 09:00:04 -0700 (PDT)


  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.
  Send mail to mime@docserver.cac.washington.edu for more info.

--Boundary_(ID_AscQuEPNMMSXRYrZaPpRTg)
Content-type: TEXT/PLAIN; charset=US-ASCII
Content-transfer-encoding: 7BIT

On Thu, 13 Sep 2001, Derek Atkins wrote:
> > 4. Apply _all_ changes to _all_ header files from
> >    /usr/src/redhat/SOURCES/linux-2.2.19-lfs.patch and
> >    /usr/src/redhat/SOURCES/linux-2.2.16-lfs-headers.patch
> >    to the header files in /usr/include/ AND /usr/src/linux-2.2.19/include/
> >    RedHat would need a separate kernel-header and kernel-source RPM for
> >    the enterprise edition to get around this (IOW: It's another bug!).
>
> Can you explain why you need to do this?  Are these patches not
> applied in the distributed kernel-source and kernel-header RPMS?
> You're saying that Red Hat applies patches to build the enterprise
> kernel AFTER it packages the kernel-source and kernel-headers?

If you look at the kernel-2.2.spec file coming with
kernel-2.2.14-5.0.src.rpm you find that for building the enterprise
kernel they apply patches, build the kernel, back out(!!) the patches
and then build the kernel header and source things.

That means the kernel-headers-2.2.19-6.2.7.i386.rpm and
kernel-source-2.2.19-6.2.7.i386.rpm do NOT fit to the enterprise kernel.
The fit to the "normal" kernel-smp-2.2.19-6.2.7 and kernel-2.2.19-6.2.7
kernels.

I have attached linux-2.2.19-lfs.patch and linux-2.2.16-lfs-headers.patch.

-- Alf.

-----------------------------------------------------------------------
  Alf Wachsmann                       | e-mail: alfw@slac.stanford.edu
  SLAC Computing Service              | Phone:  +1-650-926-4802
  2575 Sand Hill Road, M/S 97         | FAX:    +1-650-926-3329
  Menlo Park, CA 94025, USA           | Office: Bldg. 50/323
-----------------------------------------------------------------------
                http://www.slac.stanford.edu/~alfw (PGP)
-----------------------------------------------------------------------


--Boundary_(ID_AscQuEPNMMSXRYrZaPpRTg)
Content-id: <Pine.SOL.4.33.0109130900040.24390@tersk10.SLAC.Stanford.EDU>
Content-type: TEXT/PLAIN; charset=US-ASCII; name=linux-2.2.19-lfs.patch
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=linux-2.2.19-lfs.patch
Content-description: linux-2.2.19-lfs.patch

diff -urN lfs-ref/arch/alpha/kernel/entry.S lfs/arch/alpha/kernel/entry.S
--- lfs-ref/arch/alpha/kernel/entry.S	Thu Mar  1 16:38:50 2001
+++ lfs/arch/alpha/kernel/entry.S	Thu Mar  1 16:41:28 2001
@@ -8,7 +8,7 @@
 
 #define SIGCHLD 20
 
-#define NR_SYSCALLS 377
+#define NR_SYSCALLS 378
 
 /*
  * These offsets must match with alpha_mv in <asm/machvec.h>.
@@ -1153,3 +1153,4 @@
 	.quad sys_ni_syscall
 	.quad sys_ni_syscall			/* 375 */
 	.quad sys_pciconfig_iobase
+	.quad sys_getdents64
diff -urN lfs-ref/arch/alpha/kernel/osf_sys.c lfs/arch/alpha/kernel/osf_sys.c
--- lfs-ref/arch/alpha/kernel/osf_sys.c	Thu Mar  1 16:38:50 2001
+++ lfs/arch/alpha/kernel/osf_sys.c	Thu Mar  1 16:41:28 2001
@@ -110,7 +110,7 @@
 	int error;
 };
 
-static int osf_filldir(void *__buf, const char *name, int namlen, off_t offset, ino_t ino)
+static int osf_filldir(void *__buf, const char *name, int namlen, off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct osf_dirent *dirent;
 	struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
diff -urN lfs-ref/arch/i386/kernel/entry.S lfs/arch/i386/kernel/entry.S
--- lfs-ref/arch/i386/kernel/entry.S	Thu Mar  1 16:41:10 2001
+++ lfs/arch/i386/kernel/entry.S	Thu Mar  1 16:41:28 2001
@@ -571,6 +571,18 @@
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams1 */
 	.long SYMBOL_NAME(sys_ni_syscall)		/* streams2 */
 	.long SYMBOL_NAME(sys_vfork)            /* 190 */
+	.long SYMBOL_NAME(sys_ni_syscall)		/* getrlimit */
+	.long SYMBOL_NAME(sys_mmap2)		/* 192 */
+	.long SYMBOL_NAME(sys_truncate64)	/* 193 */
+	.long SYMBOL_NAME(sys_ftruncate64)	/* 194 */
+	.long SYMBOL_NAME(sys_stat64)		/* 195 */
+	.long SYMBOL_NAME(sys_lstat64)		/* 196 */
+	.long SYMBOL_NAME(sys_fstat64)		/* 197 */
+	.rept 22
+		.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
+	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_fcntl64)		/* 221 */
 
 	/*
 	 * NOTE!! This doesn't have to be exact - we just have
@@ -578,6 +590,6 @@
 	 * entries. Don't panic if you notice that this hasn't
 	 * been shrunk every time we add a new system call.
 	 */
-	.rept NR_syscalls-190
+	.rept NR_syscalls-221
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -urN lfs-ref/arch/i386/kernel/sys_i386.c lfs/arch/i386/kernel/sys_i386.c
--- lfs-ref/arch/i386/kernel/sys_i386.c	Mon Jan 17 16:44:33 2000
+++ lfs/arch/i386/kernel/sys_i386.c	Thu Mar  1 16:41:28 2001
@@ -41,6 +41,42 @@
 	return error;
 }
 
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	down(&current->mm->mmap_sem);
+	lock_kernel();
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
+	if (file)
+		fput(file);
+out:
+	unlock_kernel();
+	up(&current->mm->mmap_sem);
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
 /*
  * Perform the select(nd, in, out, ex, tv) and mmap() system
  * calls. Linux/i386 didn't use to be able to handle more than
@@ -59,30 +95,19 @@
 
 asmlinkage int old_mmap(struct mmap_arg_struct *arg)
 {
-	int error = -EFAULT;
-	struct file * file = NULL;
 	struct mmap_arg_struct a;
+	int err = -EFAULT;
 
 	if (copy_from_user(&a, arg, sizeof(a)))
-		return -EFAULT;
+		goto out;
 
-	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);
+	err = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
 
-	error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
-	if (file)
-		fput(file);
+	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
 out:
-	unlock_kernel();
-	up(&current->mm->mmap_sem);
-	return error;
+	return err;
 }
 
 extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
diff -urN lfs-ref/arch/mips/kernel/sysirix.c lfs/arch/mips/kernel/sysirix.c
--- lfs-ref/arch/mips/kernel/sysirix.c	Mon Jan 17 16:44:34 2000
+++ lfs/arch/mips/kernel/sysirix.c	Thu Mar  1 16:41:28 2001
@@ -1984,7 +1984,7 @@
 #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
 
 static int irix_filldir32(void *__buf, const char *name, int namlen,
-                          off_t offset, ino_t ino)
+                          off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct irix_dirent32 *dirent;
 	struct irix_dirent32_callback *buf =
@@ -2097,7 +2097,7 @@
 #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
 
 static int irix_filldir64(void * __buf, const char * name, int namlen,
-			  off_t offset, ino_t ino)
+			  off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct irix_dirent64 *dirent;
 	struct irix_dirent64_callback * buf =
diff -urN lfs-ref/arch/ppc/kernel/misc.S lfs/arch/ppc/kernel/misc.S
--- lfs-ref/arch/ppc/kernel/misc.S	Thu Mar  1 16:38:50 2001
+++ lfs/arch/ppc/kernel/misc.S	Thu Mar  1 16:41:28 2001
@@ -958,7 +958,7 @@
 	.long sys_swapon
 	.long sys_reboot
 	.long old_readdir
-	.long sys_mmap		/* 90 */
+	.long old_mmap		/* 90 */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
@@ -1058,18 +1058,20 @@
 	.long sys_ni_syscall		/* streams1 */
 	.long sys_ni_syscall		/* streams2 */
 	.long sys_vfork
-	.long sys_ni_syscall		/* 190 */	/* MacOnLinux - old */
+	.long sys_ni_syscall		/* 190 getrlimit */
 	.long sys_ni_syscall		/* 191 */	/* Unused */
-	.long sys_ni_syscall		/* 192 - reserved - mmap2 */
-	.long sys_ni_syscall		/* 193 - reserved - truncate64 */
-	.long sys_ni_syscall		/* 194 - reserved - ftruncate64 */
-	.long sys_ni_syscall		/* 195 - reserved - stat64 */
-	.long sys_ni_syscall		/* 196 - reserved - lstat64 */
-	.long sys_ni_syscall		/* 197 - reserved - fstat64 */
+	.long sys_mmap2			/* 192 */
+	.long sys_truncate64		/* 193 */
+	.long sys_ftruncate64		/* 194 */
+	.long sys_stat64		/* 195 */
+	.long sys_lstat64		/* 196 */
+	.long sys_fstat64		/* 197 */
 	.long sys_pciconfig_read	/* 198 */
 	.long sys_pciconfig_write 	/* 199 */
 	.long sys_pciconfig_iobase 	/* 200 */
 	.long sys_ni_syscall		/* 201 - reserved - MacOnLinux - new */
-	.rept NR_syscalls-201
+	.long sys_getdents64		/* 202 */
+	.long sys_fcntl64		/* 203 */
+	.rept NR_syscalls-203
 		.long sys_ni_syscall
 	.endr
diff -urN lfs-ref/arch/ppc/kernel/syscalls.c lfs/arch/ppc/kernel/syscalls.c
--- lfs-ref/arch/ppc/kernel/syscalls.c	Mon Dec 11 16:57:46 2000
+++ lfs/arch/ppc/kernel/syscalls.c	Thu Mar  1 16:41:28 2001
@@ -33,6 +33,7 @@
 #include <linux/sys.h>
 #include <linux/ipc.h>
 #include <linux/utsname.h>
+#include <linux/file.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -192,25 +193,55 @@
 	return error;
 }
 
-asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
-				  unsigned long prot, unsigned long flags,
-				  unsigned long fd, off_t offset)
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
 {
 	struct file * file = NULL;
 	int ret = -EBADF;
 
 	down(&current->mm->mmap_sem);
-	lock_kernel();
+
 	if (!(flags & MAP_ANONYMOUS)) {
-		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+		file = fget(fd);
+		if (!file)
 			goto out;
 	}
-	
+
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	ret = do_mmap(file, addr, len, prot, flags, offset);
-out:
+	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
+	if (file)
+		fput(file);
+ out:
 	unlock_kernel();
 	up(&current->mm->mmap_sem);
+	return ret;
+
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+			  unsigned long prot, unsigned long flags,
+			  unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+asmlinkage unsigned long old_mmap(unsigned long addr, size_t len,
+				  unsigned long prot, unsigned long flags,
+				  unsigned long fd, off_t offset)
+{
+	int ret;
+
+	ret = -EINVAL;
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	ret = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+
+ out:
 	return ret;
 }
 
diff -urN lfs-ref/arch/sparc/kernel/sys_sparc.c lfs/arch/sparc/kernel/sys_sparc.c
--- lfs-ref/arch/sparc/kernel/sys_sparc.c	Thu May  4 13:00:36 2000
+++ lfs/arch/sparc/kernel/sys_sparc.c	Thu Mar  1 16:41:28 2001
@@ -176,9 +176,9 @@
 }
 
 /* Linux version of mmap */
-asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+asmlinkage unsigned long do_mmap2(unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long fd,
-	unsigned long off)
+	unsigned long pgoff)
 {
 	struct file * file = NULL;
 	unsigned long retval = -EBADF;
@@ -211,7 +211,7 @@
 		goto out_putf;
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-	retval = do_mmap(file, addr, len, prot, flags, off);
+	retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 
 out_putf:
 	if (file)
@@ -220,6 +220,22 @@
 	unlock_kernel();
 	up(&current->mm->mmap_sem);
 	return retval;
+}
+
+asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long fd,
+	unsigned long pgoff)
+{
+	/* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE
+	   we have. */
+	return do_mmap2(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12));
+}
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long fd,
+	unsigned long off)
+{
+	return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 }
 
 /* we come to here via sys_nis_syscall so it can setup the regs argument */
diff -urN lfs-ref/arch/sparc/kernel/sys_sunos.c lfs/arch/sparc/kernel/sys_sunos.c
--- lfs-ref/arch/sparc/kernel/sys_sunos.c	Thu Mar  1 16:38:50 2001
+++ lfs/arch/sparc/kernel/sys_sunos.c	Thu Mar  1 16:41:28 2001
@@ -409,7 +409,7 @@
 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
 
 static int sunos_filldir(void * __buf, const char * name, int namlen,
-			 off_t offset, ino_t ino)
+			 off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct sunos_dirent * dirent;
 	struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
@@ -500,7 +500,7 @@
 };
 
 static int sunos_filldirentry(void * __buf, const char * name, int namlen,
-			      off_t offset, ino_t ino)
+			      off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct sunos_direntry * dirent;
 	struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf;
diff -urN lfs-ref/arch/sparc/kernel/systbls.S lfs/arch/sparc/kernel/systbls.S
--- lfs-ref/arch/sparc/kernel/systbls.S	Thu Mar  1 16:38:50 2001
+++ lfs/arch/sparc/kernel/systbls.S	Thu Mar  1 16:41:28 2001
@@ -29,12 +29,12 @@
 /*40*/	.long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_lfs_syscall
 /*45*/	.long sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
 /*50*/	.long sys_getegid, sys_acct, sys_nis_syscall, sys_nis_syscall, sys_ioctl
-/*55*/	.long sys_reboot, sys_lfs_syscall, sys_symlink, sys_readlink, sys_execve
-/*60*/	.long sys_umask, sys_chroot, sys_newfstat, sys_lfs_syscall, sys_getpagesize
+/*55*/	.long sys_reboot, sys_mmap2, sys_symlink, sys_readlink, sys_execve
+/*60*/	.long sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize
 /*65*/	.long sys_msync, sys_vfork, sys_pread, sys_pwrite, sys_nis_syscall
 /*70*/	.long sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_munmap, sys_mprotect
-/*75*/	.long sys_nis_syscall, sys_vhangup, sys_lfs_syscall, sys_nis_syscall, sys_getgroups
-/*80*/	.long sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_lfs_syscall
+/*75*/	.long sys_nis_syscall, sys_vhangup, sys_truncate64, sys_nis_syscall, sys_getgroups
+/*80*/	.long sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_ftruncate64
 /*85*/	.long sys_swapon, sys_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall
 /*90*/	.long sys_dup2, sys_nis_syscall, sys_fcntl, sys_select, sys_nis_syscall
 /*95*/	.long sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
@@ -44,12 +44,12 @@
 /*115*/	.long sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/	.long sys_readv, sys_writev, sys_settimeofday, sys_fchown, sys_fchmod
 /*125*/	.long sys_nis_syscall, sys_setreuid, sys_setregid, sys_rename, sys_truncate
-/*130*/	.long sys_ftruncate, sys_flock, sys_lfs_syscall, sys_nis_syscall, sys_nis_syscall
-/*135*/	.long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_lfs_syscall
+/*130*/	.long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
+/*135*/	.long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
 /*140*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getrlimit
 /*145*/	.long sys_setrlimit, sys_nis_syscall, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_lfs_syscall
-/*155*/	.long sys_lfs_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
+/*150*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
+/*155*/	.long sys_fcntl64, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
 /*160*/	.long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
 /*165*/	.long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
 /*170*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
diff -urN lfs-ref/arch/sparc64/kernel/sparc64_ksyms.c lfs/arch/sparc64/kernel/sparc64_ksyms.c
--- lfs-ref/arch/sparc64/kernel/sparc64_ksyms.c	Thu Mar  1 16:38:50 2001
+++ lfs/arch/sparc64/kernel/sparc64_ksyms.c	Thu Mar  1 16:41:28 2001
@@ -84,6 +84,7 @@
 extern int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
 extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
 extern void VISenter(void);
+extern long sparc32_open(const char * filename, int flags, int mode);
 extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space);
                 
 extern void bcopy (const char *, char *, int);
@@ -283,6 +284,7 @@
 EXPORT_SYMBOL(prom_cpu_nodes);
 EXPORT_SYMBOL(sys_ioctl);
 EXPORT_SYMBOL(sys32_ioctl);
+EXPORT_SYMBOL(sparc32_open);
 EXPORT_SYMBOL(move_addr_to_kernel);
 EXPORT_SYMBOL(move_addr_to_user);
 #endif
diff -urN lfs-ref/arch/sparc64/kernel/sys32.S lfs/arch/sparc64/kernel/sys32.S
--- lfs-ref/arch/sparc64/kernel/sys32.S	Thu May  4 13:00:36 2000
+++ lfs/arch/sparc64/kernel/sys32.S	Thu Mar  1 16:41:28 2001
@@ -60,3 +60,12 @@
 	sethi		%hi(sys_bdflush), %g1
 	jmpl		%g1 + %lo(sys_bdflush), %g0
 	 sra		%o1, 0, %o1
+
+	.align		32
+	.globl		sys32_mmap2
+sys32_mmap2:
+	srl		%o4, 0, %o4
+	sethi		%hi(sys_mmap), %g1
+	srl		%o5, 0, %o5
+	jmpl		%g1 + %lo(sys_mmap), %g0
+	 sllx		%o5, 12, %o5
diff -urN lfs-ref/arch/sparc64/kernel/sys_sparc32.c lfs/arch/sparc64/kernel/sys_sparc32.c
--- lfs-ref/arch/sparc64/kernel/sys_sparc32.c	Thu Mar  1 16:38:50 2001
+++ lfs/arch/sparc64/kernel/sys_sparc32.c	Thu Mar  1 16:41:28 2001
@@ -600,15 +600,27 @@
 			old_fs = get_fs(); set_fs (KERNEL_DS);
 			ret = sys_fcntl(fd, cmd, (unsigned long)&f);
 			set_fs (old_fs);
+			if (ret) return ret;
+			if (f.l_start >= 0x7fffffffUL ||
+			    f.l_len >= 0x7fffffffUL ||
+			    f.l_start + f.l_len >= 0x7fffffffUL)
+				return -EOVERFLOW;
 			if(put_flock(&f, (struct flock32 *)arg))
 				return -EFAULT;
-			return ret;
+			return 0;
 		}
 	default:
 		return sys_fcntl(fd, cmd, (unsigned long)arg);
 	}
 }
 
+asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
+		return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
+	return sys32_fcntl(fd, cmd, arg);
+}
+
 struct dqblk32 {
     __u32 dqb_bhardlimit;
     __u32 dqb_bsoftlimit;
@@ -720,6 +732,25 @@
 	return ret;
 }
 
+extern asmlinkage long sys_truncate(const char * path, unsigned long length);
+extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
+
+asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
+{
+	if ((int)high < 0)
+		return -EINVAL;
+	else
+		return sys_truncate(path, (high << 32) | low);
+}
+
+asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
+{
+	if ((int)high < 0)
+		return -EINVAL;
+	else
+		return sys_ftruncate(fd, (high << 32) | low);
+}
+
 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
 
 struct utimbuf32 {
@@ -917,7 +948,7 @@
 };
 
 static int fillonedir(void * __buf, const char * name, int namlen,
-		      off_t offset, ino_t ino)
+		      off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
 	struct old_linux_dirent32 * dirent;
@@ -982,7 +1013,8 @@
 	int error;
 };
 
-static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino,
+		   unsigned int d_type)
 {
 	struct linux_dirent32 * dirent;
 	struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
@@ -4039,6 +4071,39 @@
 		return -EFAULT;
 		
 	return ret;
+}
+
+/* This is just a version for 32-bit applications which does
+ * not force O_LARGEFILE on.
+ */
+
+asmlinkage long sparc32_open(const char * filename, int flags, int mode)
+{
+	char * tmp;
+	int fd, error;
+
+	tmp = getname(filename);
+	fd = PTR_ERR(tmp);
+	if (!IS_ERR(tmp)) {
+		lock_kernel();
+		fd = get_unused_fd();
+		if (fd >= 0) {
+			struct file * f = filp_open(tmp, flags, mode);
+			error = PTR_ERR(f);
+			if (IS_ERR(f))
+				goto out_error;
+			fd_install(fd, f);
+		}
+out:
+		unlock_kernel();
+		putname(tmp);
+	}
+	return fd;
+
+out_error:
+	put_unused_fd(fd);
+	fd = error;
+	goto out;
 }
 
 /* Handle adjtimex compatability. */
diff -urN lfs-ref/arch/sparc64/kernel/sys_sunos32.c lfs/arch/sparc64/kernel/sys_sunos32.c
--- lfs-ref/arch/sparc64/kernel/sys_sunos32.c	Thu Mar  1 16:38:50 2001
+++ lfs/arch/sparc64/kernel/sys_sunos32.c	Thu Mar  1 16:41:28 2001
@@ -366,7 +366,7 @@
 #define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1))
 
 static int sunos_filldir(void * __buf, const char * name, int namlen,
-			 off_t offset, ino_t ino)
+			 off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct sunos_dirent * dirent;
 	struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
@@ -458,7 +458,7 @@
 };
 
 static int sunos_filldirentry(void * __buf, const char * name, int namlen,
-			      off_t offset, ino_t ino)
+			      off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct sunos_direntry * dirent;
 	struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf;
@@ -1297,13 +1297,15 @@
 	return rval;
 }
 
+extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
+
 asmlinkage int sunos_open(u32 filename, int flags, int mode)
 {
 	int ret;
 
 	lock_kernel();
 	current->personality |= PER_BSD;
-	ret = sys_open ((char *)A(filename), flags, mode);
+	ret = sparc32_open ((char *)A(filename), flags, mode);
 	unlock_kernel();
 	return ret;
 }
diff -urN lfs-ref/arch/sparc64/kernel/systbls.S lfs/arch/sparc64/kernel/systbls.S
--- lfs-ref/arch/sparc64/kernel/systbls.S	Thu Mar  1 16:38:50 2001
+++ lfs/arch/sparc64/kernel/systbls.S	Thu Mar  1 16:41:28 2001
@@ -20,7 +20,7 @@
 	.globl sys_call_table32
 sys_call_table32:
 /*0*/	.word sys_nis_syscall, sparc_exit, sys_fork, sys_read, sys_write
-/*5*/	.word sys_open, sys_close, sys32_wait4, sys_creat, sys_link
+/*5*/	.word sparc32_open, sys_close, sys32_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
 /*15*/	.word sys32_chmod, sys32_lchown16, sparc_brk, sys_perfctr, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
@@ -30,12 +30,12 @@
 /*40*/	.word sys32_newlstat, sys_dup, sys_pipe, sys32_times, sys_lfs_syscall
 	.word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
 /*50*/	.word sys_getegid, sys_acct, sys_nis_syscall, sys_nis_syscall, sys32_ioctl
-	.word sys_reboot, sys_lfs_syscall, sys_symlink, sys_readlink, sys32_execve
-/*60*/	.word sys_umask, sys_chroot, sys32_newfstat, sys_lfs_syscall, sys_getpagesize
+	.word sys_reboot, sys32_mmap2, sys_symlink, sys_readlink, sys32_execve
+/*60*/	.word sys_umask, sys_chroot, sys32_newfstat, sys_fstat64, sys_getpagesize
 	.word sys_msync, sys_vfork, sys32_pread, sys32_pwrite, sys_nis_syscall
 /*70*/	.word sys_nis_syscall, sys32_mmap, sys_nis_syscall, sys_munmap, sys_mprotect
-	.word sys_nis_syscall, sys_vhangup, sys_lfs_syscall, sys_nis_syscall, sys32_getgroups
-/*80*/	.word sys32_setgroups, sys_getpgrp, sys_nis_syscall, sys32_setitimer, sys_lfs_syscall
+	.word sys_nis_syscall, sys_vhangup, sys32_truncate64, sys_nis_syscall, sys32_getgroups
+/*80*/	.word sys32_setgroups, sys_getpgrp, sys_nis_syscall, sys32_setitimer, sys32_ftruncate64
 	.word sys_swapon, sys32_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall
 /*90*/	.word sys_dup2, sys_nis_syscall, sys32_fcntl, sys32_select, sys_nis_syscall
 	.word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
@@ -45,12 +45,12 @@
 	.word sys_nis_syscall, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/	.word sys32_readv, sys32_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
 	.word sys_nis_syscall, sys32_setreuid, sys32_setregid, sys_rename, sys_truncate
-/*130*/	.word sys_ftruncate, sys_flock, sys_lfs_syscall, sys_nis_syscall, sys_nis_syscall
-	.word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_lfs_syscall
+/*130*/	.word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
+	.word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_stat64
 /*140*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getrlimit
 	.word sys32_setrlimit, sys_nis_syscall, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write
-/*150*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_lfs_syscall
-	.word sys_lfs_syscall, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
+/*150*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
+	.word sys32_fcntl64, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
 /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
 	.word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
 /*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
@@ -108,7 +108,7 @@
 	.word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_nis_syscall
 /*140*/	.word sys_nis_syscall, sys_getpeername, sys_nis_syscall, sys_nis_syscall, sys_getrlimit
 	.word sys_setrlimit, sys_nis_syscall, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/	.word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall
+/*150*/	.word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
 	.word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
 /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
 	.word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
diff -urN lfs-ref/arch/sparc64/solaris/fs.c lfs/arch/sparc64/solaris/fs.c
--- lfs-ref/arch/sparc64/solaris/fs.c	Mon Jan 17 16:44:36 2000
+++ lfs/arch/sparc64/solaris/fs.c	Thu Mar  1 16:41:28 2001
@@ -572,20 +572,20 @@
 	return error;
 }
 
+extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
+
 asmlinkage int solaris_open(u32 filename, int flags, u32 mode)
 {
-	int (*sys_open)(const char *,int,int) = 
-		(int (*)(const char *,int,int))SYS(open);
 	int fl = flags & 0xf;
 
-/*	if (flags & 0x2000) - allow LFS			*/
+	if (flags & 0x2000) fl |= O_LARGEFILE;
 	if (flags & 0x8050) fl |= O_SYNC;
 	if (flags & 0x80) fl |= O_NONBLOCK;
 	if (flags & 0x100) fl |= O_CREAT;
 	if (flags & 0x200) fl |= O_TRUNC;
 	if (flags & 0x400) fl |= O_EXCL;
 	if (flags & 0x800) fl |= O_NOCTTY;
-	return sys_open((const char *)A(filename), fl, mode);
+	return sparc32_open((const char *)A(filename), fl, mode);
 }
 
 #define SOL_F_SETLK	6
diff -urN lfs-ref/drivers/usb/inode.c lfs/drivers/usb/inode.c
--- lfs-ref/drivers/usb/inode.c	Mon Dec 11 16:57:58 2000
+++ lfs/drivers/usb/inode.c	Thu Mar  1 16:41:28 2001
@@ -302,14 +302,14 @@
 	i = filp->f_pos;
 	switch (i) {
 	case 0:
-		if (filldir(dirent, ".", 1, i, IROOT) < 0)
+		if (filldir(dirent, ".", 1, i, IROOT, DT_DIR) < 0)
 			return 0;
 		filp->f_pos++;
 		i++;
 		/* fall through */
 
 	case 1:
-		if (filldir(dirent, "..", 2, i, IROOT) < 0)
+		if (filldir(dirent, "..", 2, i, IROOT, DT_DIR) < 0)
 			return 0;
 		filp->f_pos++;
 		i++;
@@ -319,7 +319,7 @@
 		
 		while (i >= 2 && i < 2+NRSPECIAL) {
 			spec = &special[filp->f_pos-2];
-			if (filldir(dirent, spec->name, strlen(spec->name), i, ISPECIAL | (filp->f_pos-2+IROOT)) < 0)
+			if (filldir(dirent, spec->name, strlen(spec->name), i, ISPECIAL | (filp->f_pos-2+IROOT), DT_UNKNOWN) < 0)
 				return 0;
 			filp->f_pos++;
 			i++;
@@ -335,7 +335,7 @@
 			}
 			bus = list_entry(list, struct usb_bus, bus_list);
 			sprintf(numbuf, "%03d", bus->busnum);
-			if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS | ((bus->busnum & 0xff) << 8)) < 0)
+			if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS | ((bus->busnum & 0xff) << 8), DT_UNKNOWN) < 0)
 				break;
 			filp->f_pos++;
 		}
@@ -355,7 +355,7 @@
 	if (pos > 0)
 		pos--;
 	else {
-		if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum & 0xff)) < 0)
+		if (filldir(dirent, numbuf, 3, filp->f_pos, ino | (dev->devnum & 0xff), DT_UNKNOWN) < 0)
 			return -1;
 		filp->f_pos++;
 	}
@@ -380,13 +380,13 @@
 		return -EINVAL;
 	switch ((unsigned int)filp->f_pos) {
 	case 0:
-		if (filldir(dirent, ".", 1, filp->f_pos, ino) < 0)
+		if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos++;
 		/* fall through */
 
 	case 1:
-		if (filldir(dirent, "..", 2, filp->f_pos, IROOT) < 0)
+		if (filldir(dirent, "..", 2, filp->f_pos, IROOT, DT_DIR) < 0)
 			return 0;
 		filp->f_pos++;
 		/* fall through */
diff -urN lfs-ref/fs/adfs/dir.c lfs/fs/adfs/dir.c
--- lfs-ref/fs/adfs/dir.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/adfs/dir.c	Thu Mar  1 16:41:28 2001
@@ -40,12 +40,12 @@
 
 	switch ((unsigned long)filp->f_pos) {
 	case 0:
-		if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0)
+		if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
 			goto free_out;
 		filp->f_pos += 1;
 
 	case 1:
-		if (filldir(dirent, "..", 2, 1, dir.parent_id) < 0)
+		if (filldir(dirent, "..", 2, 1, dir.parent_id, DT_DIR) < 0)
 			goto free_out;
 		filp->f_pos += 1;
 
@@ -60,7 +60,7 @@
 		goto unlock_out;
 	while (ops->getnext(&dir, &obj) == 0) {
 		if (filldir(dirent, obj.name, obj.name_len,
-			    filp->f_pos, obj.file_id) < 0)
+			    filp->f_pos, obj.file_id, DT_UNKNOWN) < 0)
 			goto unlock_out;
 		filp->f_pos += 1;
 	}
diff -urN lfs-ref/fs/affs/dir.c lfs/fs/affs/dir.c
--- lfs-ref/fs/affs/dir.c	Mon Jan 17 16:44:41 2000
+++ lfs/fs/affs/dir.c	Thu Mar  1 16:41:28 2001
@@ -98,14 +98,14 @@
 
 	if (filp->f_pos == 0) {
 		filp->private_data = (void *)0;
-		if (filldir(dirent,".",1,filp->f_pos,inode->i_ino) < 0) {
+		if (filldir(dirent,".",1,filp->f_pos,inode->i_ino, DT_DIR) < 0) {
 			return 0;
 		}
 		++filp->f_pos;
 		stored++;
 	}
 	if (filp->f_pos == 1) {
-		if (filldir(dirent,"..",2,filp->f_pos,affs_parent_ino(inode)) < 0) {
+		if (filldir(dirent,"..",2,filp->f_pos,affs_parent_ino(inode), DT_DIR) < 0) {
 			return stored;
 		}
 		filp->f_pos = 2;
@@ -161,7 +161,7 @@
 			pr_debug("AFFS: readdir(): filldir(\"%.*s\",ino=%lu), i=%d\n",
 				 namelen,name,ino,i);
 			filp->private_data = (void *)ino;
-			if (filldir(dirent,name,namelen,filp->f_pos,ino) < 0)
+			if (filldir(dirent,name,namelen,filp->f_pos,ino, DT_UNKNOWN) < 0)
 				goto readdir_done;
 			filp->private_data = (void *)i;
 			affs_brelse(fh_bh);
diff -urN lfs-ref/fs/affs/file.c lfs/fs/affs/file.c
--- lfs-ref/fs/affs/file.c	Tue Sep  5 02:28:47 2000
+++ lfs/fs/affs/file.c	Thu Mar  1 16:41:28 2001
@@ -582,17 +582,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");
@@ -611,16 +611,22 @@
 	else
 		pos = *ppos;
 	written   = 0;
-	blocksize = AFFS_I2BSIZE(inode);
+	blocksize  = AFFS_I2BSIZE(inode);
+	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)) {
@@ -633,7 +639,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);
@@ -664,7 +670,7 @@
 	off_t			 pos;
 	ssize_t			 written;
 	ssize_t			 c;
-	ssize_t			 blocksize;
+	ssize_t			 blocksize, blockshift;
 	struct buffer_head	*bh;
 	char			*p;
 
@@ -692,15 +698,16 @@
 
 	bh        = NULL;
 	blocksize = AFFS_I2BSIZE(inode) - 24;
+	blockshift = AFFS_I2BITS(inode);
 	written   = 0;
 	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)) {
@@ -713,7 +720,7 @@
 				break;
 			}
 		}
-		p  = (pos % blocksize) + bh->b_data + 24;
+		p  = (pos & (blocksize -1)) + bh->b_data + 24;
 		c -= copy_from_user(p,buf,c);
 		if (!c) {
 			affs_brelse(bh);
@@ -782,10 +789,10 @@
 	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);
 
 	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,9 +802,9 @@
 		bh = affs_getblock(inode,first - 1);
 		if (!bh) {
 			affs_warning(inode->i_sb,"truncate","Cannot extend file");
-			inode->i_size = net_blocksize * (inode->u.affs_i.i_lastblock + 1);
+			inode->i_size = (inode->u.affs_i.i_lastblock + 1) * net_blocksize;
 		} 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 -1);
 			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);
@@ -864,7 +871,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,
@@ -872,7 +879,7 @@
 	 * so it cannot become accessible again.
 	 */
 
-	rem = inode->i_size % net_blocksize;
+	rem = inode->i_size & (net_blocksize -1);
 	if (rem) {
 		if ((inode->i_sb->u.affs_sb.s_flags & SF_OFS)) 
 			rem += 24;
diff -urN lfs-ref/fs/affs/inode.c lfs/fs/affs/inode.c
--- lfs-ref/fs/affs/inode.c	Sun Apr  2 21:07:49 2000
+++ lfs/fs/affs/inode.c	Thu Mar  1 16:41:28 2001
@@ -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 -urN lfs-ref/fs/autofs/dir.c lfs/fs/autofs/dir.c
--- lfs-ref/fs/autofs/dir.c	Mon Jan 17 16:44:41 2000
+++ lfs/fs/autofs/dir.c	Thu Mar  1 16:41:28 2001
@@ -20,12 +20,12 @@
 	switch((unsigned long) filp->f_pos)
 	{
 	case 0:
-		if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0)
+		if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos++;
 		/* fall through */
 	case 1:
-		if (filldir(dirent, "..", 2, 1, AUTOFS_ROOT_INO) < 0)
+		if (filldir(dirent, "..", 2, 1, AUTOFS_ROOT_INO, DT_DIR) < 0)
 			return 0;
 		filp->f_pos++;
 		/* fall through */
diff -urN lfs-ref/fs/autofs/root.c lfs/fs/autofs/root.c
--- lfs-ref/fs/autofs/root.c	Mon Jan 17 16:44:41 2000
+++ lfs/fs/autofs/root.c	Thu Mar  1 16:41:28 2001
@@ -79,19 +79,19 @@
 	switch(nr)
 	{
 	case 0:
-		if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
+		if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
 	case 1:
-		if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
+		if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
 	default:
 		while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent) ) {
 			if ( !ent->dentry || ent->dentry->d_mounts != ent->dentry ) {
-				if (filldir(dirent,ent->name,ent->len,onr,ent->ino) < 0)
+				if (filldir(dirent,ent->name,ent->len,onr,ent->ino, DT_UNKNOWN) < 0)
 					return 0;
 				filp->f_pos = nr;
 			}
diff -urN lfs-ref/fs/binfmt_aout.c lfs/fs/binfmt_aout.c
--- lfs-ref/fs/binfmt_aout.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/binfmt_aout.c	Thu Mar  1 16:41:28 2001
@@ -410,7 +410,11 @@
 		file = fget(fd);
 
 		if (!file->f_op || !file->f_op->mmap ||
+#if 0
 		    fd_offset & (bprm->dentry->d_inode->i_sb->s_blocksize-1)) {
+#else /* LFS enforces PAGE_SIZE file offset granularity in mmap */
+		    fd_offset & ~PAGE_MASK) {
+#endif
 			if (warnings++<10)
 				printk(KERN_NOTICE
 				       "fd_offset is not blocksize aligned. Loading %s in anonymous memory.\n",
@@ -532,7 +536,11 @@
 
 	start_addr =  ex.a_entry & 0xfffff000;
 
+#if 0
 	if (N_TXTOFF(ex) & (inode->i_sb->s_blocksize-1)) {
+#else /* LFS enforces PAGE_SIZE file offset granularity in mmap */
+	if (N_TXTOFF(ex) & ~PAGE_MASK) {
+#endif
 		if (warnings++<10)
 			printk(KERN_NOTICE
 			       "N_TXTOFF is not blocksize aligned. Loading library %s in anonymous memory.\n",
diff -urN lfs-ref/fs/buffer.c lfs/fs/buffer.c
--- lfs-ref/fs/buffer.c	Thu Mar  1 16:41:12 2001
+++ lfs/fs/buffer.c	Thu Mar  1 16:41:28 2001
@@ -1219,7 +1219,7 @@
 #endif
 	}
 	if (test_and_clear_bit(PG_swap_unlock_after, &page->flags))
-		swap_after_unlock_page(page->offset);
+		swap_after_unlock_page(pgoff2ulong(page->index));
 	if (test_and_clear_bit(PG_free_after, &page->flags))
 		__free_page(page);
 }
@@ -1671,15 +1671,46 @@
 	set_bit(PG_locked, &page->flags);
 	set_bit(PG_free_after, &page->flags);
 	
+	/* Blocks within a page */
 	i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
-	block = page->offset >> inode->i_sb->s_blocksize_bits;
-	p = nr;
-	do {
-		*p = inode->i_op->bmap(inode, block);
-		i--;
-		block++;
-		p++;
-	} while (i > 0);
+
+	block = pgoff2ulong(page->index);
+	/* Scaled already by PAGE_SHIFT, which said shift should
+	   be same or larger, than that of any filesystem in
+	   this system -- that is, at i386 with 4k pages one
+	   can't use 8k (primitive) blocks at the filesystems... */
+
+	if (i > 0) {
+		/* Filesystem blocksize is same, or smaller than CPU
+		   page size, we can easily process this.. */
+
+		if (i > 1)
+			block *= i;
+		/* Scale by FS blocks per page, presuming FS-blocks are smaller
+		   than the processor page... */
+
+		p = nr;
+		do {
+			*p = inode->i_op->bmap(inode, block);
+			i--;
+			block++;
+			p++;
+		} while (i > 0);
+	} else {
+		/* Filesystem blocksize is larger than CPU page size,
+		   but if the underlying storage system block size is
+		   smaller than CPU page size, all is well, else we
+		   are in deep trouble -- for direct paging in at least.. */
+		/* Nobody needs such monsterous fs block sizes ?
+		   Well, it is the only way to get files in terabyte
+		   range..  Nobody needs them ?  You are for a surprise..
+		   However EXT2 (at least) needs access to internal
+		   blocks and there it needs allocations of 8k/16k (or
+		   whatever the block size is) for internal uses..
+		   Fixing this function alone isn't enough, although
+		   perhaps fairly trivial.. */
+		/* FIXME: WRITE THE CODE HERE !!! */
+	}
 
 	/* IO start */
 	brw_page(READ, page, inode->i_dev, nr, inode->i_sb->s_blocksize, 1);
diff -urN lfs-ref/fs/coda/dir.c lfs/fs/coda/dir.c
--- lfs-ref/fs/coda/dir.c	Tue Sep  5 02:28:47 2000
+++ lfs/fs/coda/dir.c	Thu Mar  1 16:41:28 2001
@@ -749,7 +749,7 @@
                         char *name  = vdirent->d_name;
 
 			errfill = filldir(getdent,  name, namlen, 
-					  offs, ino); 
+					  offs, ino, DT_UNKNOWN);
 CDEBUG(D_FILE, "entry %d: ino %ld, namlen %d, reclen %d, type %d, pos %d, string_offs %d, name %*s, offset %d, result: %d, errfill: %d.\n", i,vdirent->d_fileno, vdirent->d_namlen, vdirent->d_reclen, vdirent->d_type, pos,  string_offset, vdirent->d_namlen, vdirent->d_name, (u_int) offs, result, errfill);
 			/* errfill means no space for filling in this round */
 			if ( errfill < 0 ) {
diff -urN lfs-ref/fs/coda/file.c lfs/fs/coda/file.c
--- lfs-ref/fs/coda/file.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/coda/file.c	Thu Mar  1 16:41:28 2001
@@ -99,7 +99,7 @@
 			      &cont_file, &cont_dentry);
 
         CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", 
-	       coda_inode->i_ino, cii->c_ovp->i_ino, page->offset);
+	       coda_inode->i_ino, cii->c_ovp->i_ino, pgoff2ulong(page->index));
 
         generic_readpage(&cont_file, page);
         EXIT;
diff -urN lfs-ref/fs/devpts/root.c lfs/fs/devpts/root.c
--- lfs-ref/fs/devpts/root.c	Mon Jan 17 16:44:41 2000
+++ lfs/fs/devpts/root.c	Thu Mar  1 16:41:28 2001
@@ -86,12 +86,12 @@
 	switch(nr)
 	{
 	case 0:
-		if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
+		if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
 	case 1:
-		if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
+		if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
@@ -100,7 +100,7 @@
 			int ptynr = nr - 2;
 			if ( sbi->inodes[ptynr] ) {
 				genptsname(numbuf, ptynr);
-				if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr) < 0 )
+				if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_CHR) < 0 )
 					return 0;
 			}
 			filp->f_pos = ++nr;
diff -urN lfs-ref/fs/dquot.c lfs/fs/dquot.c
--- lfs-ref/fs/dquot.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/dquot.c	Thu Mar  1 16:41:28 2001
@@ -1535,7 +1535,7 @@
 	if (!S_ISREG(inode->i_mode))
 		goto out_f;
 	error = -EINVAL;
-	if (inode->i_size == 0 || (inode->i_size % sizeof(struct dqblk)) != 0)
+	if (inode->i_size == 0 || ((off_t)inode->i_size % sizeof(struct dqblk)) != 0)
 		goto out_f;
 	dquot_drop(inode);	/* We don't want quota on quota files */
 
diff -urN lfs-ref/fs/efs/dir.c lfs/fs/efs/dir.c
--- lfs-ref/fs/efs/dir.c	Mon Jan 17 16:44:41 2000
+++ lfs/fs/efs/dir.c	Thu Mar  1 16:41:28 2001
@@ -107,7 +107,7 @@
 				filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
 
 				/* copy filename and data in dirslot */
-				filldir(dirent, nameptr, namelen, filp->f_pos, inodenum);
+				filldir(dirent, nameptr, namelen, filp->f_pos, inodenum, DT_UNKNOWN);
 
 				/* sanity check */
 				if (nameptr - (char *) dirblock + namelen > EFS_DIRBSIZE) {
diff -urN lfs-ref/fs/ext2/dir.c lfs/fs/ext2/dir.c
--- lfs-ref/fs/ext2/dir.c	Thu May  4 13:00:39 2000
+++ lfs/fs/ext2/dir.c	Thu Mar  1 16:41:28 2001
@@ -32,6 +32,10 @@
 	return -EISDIR;
 }
 
+static unsigned char ext2_filetype_table[] = {
+	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+};
+
 static int ext2_readdir(struct file *, void *, filldir_t);
 
 static struct file_operations ext2_dir_operations = {
@@ -201,10 +205,14 @@
 				 * the descriptor.
 				 */
 				unsigned long version = filp->f_version;
+				unsigned char d_type = DT_UNKNOWN;
 
+				if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)
+				    && de->file_type < EXT2_FT_MAX)
+					d_type = ext2_filetype_table[de->file_type];
 				error = filldir(dirent, de->name,
 						de->name_len,
-						filp->f_pos, le32_to_cpu(de->inode));
+						filp->f_pos, le32_to_cpu(de->inode), d_type);
 				if (error)
 					break;
 				if (version != filp->f_version)
diff -urN lfs-ref/fs/ext2/file.c lfs/fs/ext2/file.c
--- lfs-ref/fs/ext2/file.c	Thu Mar  1 16:41:11 2001
+++ lfs/fs/ext2/file.c	Thu Mar  1 16:41:28 2001
@@ -39,10 +39,6 @@
 static long long ext2_file_lseek(struct file *, long long, int);
 static ssize_t ext2_file_write (struct file *, const char *, size_t, loff_t *);
 static int ext2_release_file (struct inode *, struct file *);
-#if BITS_PER_LONG < 64
-static int ext2_open_file (struct inode *, struct file *);
-
-#else
 
 #define EXT2_MAX_SIZE(bits)							\
 	(((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) + 				\
@@ -55,8 +51,6 @@
 EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
 };
 
-#endif
-
 /*
  * We have mostly NULL's here: the current defaults are ok for
  * the ext2 filesystem.
@@ -69,11 +63,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 */
@@ -120,14 +110,9 @@
 		case 1:
 			offset += file->f_pos;
 	}
-#if BITS_PER_LONG < 64
-	if (offset >> 31)
-		return -EINVAL;
-#else
 	if (offset < 0 ||
 	    offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
 		return -EINVAL;
-#endif
 	if (offset != file->f_pos) {
 		file->f_pos = offset;
 		file->f_reada = 0;
@@ -155,7 +140,7 @@
 				size_t count, loff_t *ppos)
 {
 	struct inode * inode = filp->f_dentry->d_inode;
-	off_t pos;
+	loff_t pos;
 	long block;
 	int offset;
 	size_t written, c;
@@ -202,24 +187,19 @@
 
 	/* Check for overflow.. */
 
-#if BITS_PER_LONG < 64
+#if 1
-	/* If the fd's pos is already greater than or equal to the file
-	 * descriptor's offset maximum, then we need to return EFBIG for
-	 * any non-zero count (and we already tested for zero above). */
-	if (((unsigned) pos) >= 0x7FFFFFFFUL)
-		return -EFBIG;
-	
-	/* If we are about to overflow the maximum file size, we also
-	 * need to return the error, but only if no bytes can be written
-	 * successfully. */
-	if (((unsigned) pos + count) > 0x7FFFFFFFUL) {
-		count = 0x7FFFFFFFL - pos;
-		if (((signed) count) < 0)
+	/* L-F-S spec 2.2.1.27: */
+	if (!(filp->f_flags & O_LARGEFILE)) {
+		if (pos >= 0x7fffffffULL) /* pos@2G forbidden */
 			return -EFBIG;
+
+		if (pos + count > 0x7fffffffULL)
+			/* Write only until end of allowed region */
+			count = 0x7fffffffULL - pos;
 	}
-#else
+
 	{
-		off_t max = ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(sb)];
+		loff_t max = ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(sb)];
 
 		if (pos >= max)
 			return -EFBIG;
@@ -382,15 +359,3 @@
 	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.
- */
-static int ext2_open_file (struct inode * inode, struct file * filp)
-{
-	if (inode->u.ext2_i.i_high_size && (filp->f_mode & FMODE_WRITE))
-		return -EFBIG;
-	return 0;
-}
-#endif
diff -urN lfs-ref/fs/ext2/inode.c lfs/fs/ext2/inode.c
--- lfs-ref/fs/ext2/inode.c	Thu Mar  1 16:41:11 2001
+++ lfs/fs/ext2/inode.c	Thu Mar  1 16:41:28 2001
@@ -537,15 +537,8 @@
 		inode->u.ext2_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
 	else {
 		inode->u.ext2_i.i_dir_acl = 0;
-		inode->u.ext2_i.i_high_size =
-			le32_to_cpu(raw_inode->i_size_high);
-#if BITS_PER_LONG < 64
-		if (raw_inode->i_size_high)
-			inode->i_size = (__u32)-1;
-#else
-		inode->i_size |= ((__u64)le32_to_cpu(raw_inode->i_size_high))
-			<< 32;
-#endif
+		inode->i_size = ((__u64)(inode->i_size & 0xFFFFFFFFUL)) |
+			(((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32);
 	}
 	inode->u.ext2_i.i_block_group = block_group;
 	inode->u.ext2_i.i_next_alloc_block = 0;
@@ -667,12 +660,7 @@
 	if (S_ISDIR(inode->i_mode))
 		raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext2_i.i_dir_acl);
 	else { 
-#if BITS_PER_LONG < 64
-		raw_inode->i_size_high =
-			cpu_to_le32(inode->u.ext2_i.i_high_size);
-#else
 		raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32);
-#endif
 	}
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
@@ -724,21 +712,18 @@
 	}
 
 	if (iattr->ia_valid & ATTR_SIZE) {
-		off_t size = iattr->ia_size;
+		loff_t size = iattr->ia_size;
 		unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
 
 		if (size < 0)
 			return -EINVAL;
-#if BITS_PER_LONG == 64	
 		if (size > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
 			return -EFBIG;
-#endif
-		if (limit < RLIM_INFINITY && size > limit) {
+		if (limit != RLIM_INFINITY && size > limit) {
 			send_sig(SIGXFSZ, current, 0);
 			return -EFBIG;
 		}
 
-#if BITS_PER_LONG == 64	
 		if (size >> 33) {
 			struct super_block *sb = inode->i_sb;
 			struct ext2_super_block *es = sb->u.ext2_sb.s_es;
@@ -751,7 +736,6 @@
 				mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
 			}
 		}
-#endif
 	}
 	
 	retval = inode_change_ok(inode, iattr);
diff -urN lfs-ref/fs/ext2/truncate.c lfs/fs/ext2/truncate.c
--- lfs-ref/fs/ext2/truncate.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/ext2/truncate.c	Thu Mar  1 16:41:28 2001
@@ -53,9 +53,10 @@
  * Currently we always hold the inode semaphore during truncate, so
  * there's no need to test for changes during the operation.
  */
-#define DIRECT_BLOCK(inode) \
-	((inode->i_size + inode->i_sb->s_blocksize - 1) / \
-			  inode->i_sb->s_blocksize)
+#define DIRECT_BLOCK(inode)	\
+	((long)			\
+	 ((inode->i_size + inode->i_sb->s_blocksize - 1) >> \
+			  inode->i_sb->s_blocksize_bits))
 #define INDIRECT_BLOCK(inode,offset) ((int)DIRECT_BLOCK(inode) - offset)
 #define DINDIRECT_BLOCK(inode,offset) \
 	(INDIRECT_BLOCK(inode,offset) / addr_per_block)
diff -urN lfs-ref/fs/fat/dir.c lfs/fs/fat/dir.c
--- lfs-ref/fs/fat/dir.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/fat/dir.c	Thu Mar  1 16:41:28 2001
@@ -315,7 +315,7 @@
 /* Fake . and .. for the root directory. */
 	if (inode->i_ino == MSDOS_ROOT_INO) {
 		while (cpos < 2) {
-			if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO) < 0)
+			if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0)
 				return 0;
 			cpos++;
 			filp->f_pos++;
@@ -458,7 +458,8 @@
 	if (!long_slots||shortnames) {
 		if (both)
 			bufname[i] = '\0';
-		if (filldir(dirent, bufname, i, *furrfu, inum) < 0)
+		if (filldir(dirent, bufname, i, *furrfu, inum,
+			    (de->attr & ATTR_DIR) ? DT_DIR : DT_REG) < 0)
 			goto FillFailed;
 	} else {
 		char longname[275];
@@ -469,7 +470,8 @@
 			memcpy(&longname[long_len+1], bufname, i);
 			long_len += i;
 		}
-		if (filldir(dirent, longname, long_len, *furrfu, inum) < 0)
+		if (filldir(dirent, longname, long_len, *furrfu, inum,
+			    (de->attr & ATTR_DIR) ? DT_DIR : DT_REG) < 0)
 			goto FillFailed;
 	}
 
@@ -499,7 +501,8 @@
 	const char * name,
 	int name_len,
 	off_t offset,
-	ino_t ino)
+	ino_t ino,
+	unsigned int d_type)
 {
 	struct dirent *d1 = (struct dirent *)buf;
 	struct dirent *d2 = d1 + 1;
diff -urN lfs-ref/fs/fat/file.c lfs/fs/fat/file.c
--- lfs-ref/fs/fat/file.c	Mon Jan 17 16:44:42 2000
+++ lfs/fs/fat/file.c	Thu Mar  1 16:41:28 2001
@@ -227,7 +227,7 @@
 		Each time we process one block in bhlist, we replace
 		it by a new prefetch block if needed.
 	*/
-	PRINTK (("#### ino %ld pos %ld size %ld count %d\n",inode->i_ino,*ppos,inode->i_size,count));
+	PRINTK (("#### ino %ld pos %ld size %ld count %d\n",inode->i_ino,*ppos,(u_long)inode->i_size,count));
 	{
 		/*
 			We must prefetch complete block, so we must
@@ -253,7 +253,7 @@
 	}
 	pre.nolist = 0;
 	PRINTK (("count %d ahead %d nblist %d\n",count,read_ahead[MAJOR(inode->i_dev)],pre.nblist));
-	while ((left_in_file = inode->i_size - *ppos) > 0
+	while ((left_in_file = (u_long)inode->i_size - *ppos) > 0
 		&& buf < end){
 		struct buffer_head *bh = pre.bhlist[pre.nolist];
 		char *data;
@@ -451,7 +451,7 @@
 
 void fat_truncate(struct inode *inode)
 {
-	int cluster;
+	int cluster_bytes, cluster_shift;
 
 	/* Why no return value?  Surely the disk could fail... */
 	if (IS_IMMUTABLE(inode))
@@ -460,8 +460,10 @@
 		printk("FAT: fat_truncate called though fs is read-only, uhh...\n");
 		return /* -EROFS */;
 	}
-	cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
-	(void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
+	cluster_bytes = SECTOR_SIZE * MSDOS_SB(inode->i_sb)->cluster_size;
+	cluster_shift = fslog2(cluster_bytes);
+	(void) fat_free(inode,
+			(inode->i_size+(cluster_bytes-1)) >> cluster_shift);
 	MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
 	mark_inode_dirty(inode);
 }
diff -urN lfs-ref/fs/fat/inode.c lfs/fs/fat/inode.c
--- lfs-ref/fs/fat/inode.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/fat/inode.c	Thu Mar  1 16:41:28 2001
@@ -399,8 +399,9 @@
 			sizeof(struct msdos_dir_entry);
 	}
 	inode->i_blksize = MSDOS_SB(sb)->cluster_size* SECTOR_SIZE;
-	inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
-		    inode->i_blksize*MSDOS_SB(sb)->cluster_size;
+		inode->i_blocks = (((inode->i_size+inode->i_blksize-1) >>
+				    fslog2(inode->i_blksize)) *
+				   MSDOS_SB(sb)->cluster_size);
 	MSDOS_I(inode)->i_logstart = 0;
 
 	MSDOS_I(inode)->i_attrs = 0;
@@ -830,8 +831,9 @@
 	MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
 	/* this is as close to the truth as we can get ... */
 	inode->i_blksize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
-	inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
-	    inode->i_blksize*MSDOS_SB(sb)->cluster_size;
+	inode->i_blocks = (((inode->i_size+inode->i_blksize-1) >>
+			    fslog2(inode->i_blksize)) *
+			   MSDOS_SB(sb)->cluster_size);
 	inode->i_mtime = inode->i_atime =
 	    date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date));
 	inode->i_ctime =
diff -urN lfs-ref/fs/fcntl.c lfs/fs/fcntl.c
--- lfs-ref/fs/fcntl.c	Thu Mar  1 16:41:10 2001
+++ lfs/fs/fcntl.c	Thu Mar  1 16:41:28 2001
@@ -145,17 +145,11 @@
 	return 0;
 }
 
-asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{	
-	struct file * filp;
-	long err = -EBADF;
-
-	lock_kernel();
-	filp = fget(fd);
-	if (!filp)
-		goto out;
+static long do_fcntl(unsigned int fd, unsigned int cmd,
+		     unsigned long arg, struct file * filp)
+{
+	long err = 0;
 
-	err = 0;
 	switch (cmd) {
 		case F_DUPFD:
 			err = dupfd(fd, arg);
@@ -219,11 +213,60 @@
 				err = sock_fcntl (filp, cmd, arg);
 			break;
 	}
+
+	return err;
+}
+
+asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{	
+	struct file * filp;
+	long err = -EBADF;
+
+	lock_kernel();
+	filp = fget(fd);
+	if (!filp)
+		goto out;
+
+	err = do_fcntl(fd, cmd, arg, filp);
+
+	fput(filp);
+out:
+	unlock_kernel();
+	return err;
+}
+
+#if BITS_PER_LONG == 32
+asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
+{	
+	struct file * filp;
+	long err = -EBADF;
+
+	lock_kernel();
+	filp = fget(fd);
+	if (!filp)
+		goto out;
+
+	switch (cmd) {
+		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;
+		default:
+			err = do_fcntl(fd, cmd, arg, filp);
+			break;
+	}
+
 	fput(filp);
 out:
 	unlock_kernel();
 	return err;
 }
+#endif
 
 /* Table to convert sigio signal codes into poll band bitmaps */
 
diff -urN lfs-ref/fs/hfs/dir_cap.c lfs/fs/hfs/dir_cap.c
--- lfs-ref/fs/hfs/dir_cap.c	Mon Jan 17 16:44:42 2000
+++ lfs/fs/hfs/dir_cap.c	Thu Mar  1 16:41:28 2001
@@ -243,7 +243,7 @@
 
 	if (filp->f_pos == 0) {
 		/* Entry 0 is for "." */
-		if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
+		if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, DT_DIR)) {
 			return 0;
 		}
 		filp->f_pos = 1;
@@ -260,7 +260,7 @@
 		}
 
 		if (filldir(dirent, DOT_DOT->Name,
-			    DOT_DOT_LEN, 1, ntohl(cnid))) {
+			    DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) {
 			return 0;
 		}
 		filp->f_pos = 2;
@@ -287,7 +287,7 @@
 				len = hfs_namein(dir, tmp_name,
 				    &((struct hfs_cat_key *)brec.key)->CName);
 				if (filldir(dirent, tmp_name, len,
-					    filp->f_pos, ino)) {
+					    filp->f_pos, ino, DT_UNKNOWN)) {
 					hfs_cat_close(entry, &brec);
 					return 0;
 				}
@@ -303,7 +303,7 @@
 			/* In root dir last-2 entry is for ".rootinfo" */
 			if (filldir(dirent, DOT_ROOTINFO->Name,
 				    DOT_ROOTINFO_LEN, filp->f_pos,
-				    ntohl(entry->cnid) | HFS_CAP_FNDR)) {
+				    ntohl(entry->cnid) | HFS_CAP_FNDR, DT_UNKNOWN)) {
 				return 0;
 			}
 		}
@@ -315,7 +315,7 @@
 			/* In normal dirs last-1 entry is for ".finderinfo" */
 			if (filldir(dirent, DOT_FINDERINFO->Name,
 				    DOT_FINDERINFO_LEN, filp->f_pos,
-				    ntohl(entry->cnid) | HFS_CAP_FDIR)) {
+				    ntohl(entry->cnid) | HFS_CAP_FDIR, DT_UNKNOWN)) {
 				return 0;
 			}
 		}
@@ -327,7 +327,7 @@
 			/* In normal dirs last entry is for ".resource" */
 			if (filldir(dirent, DOT_RESOURCE->Name,
 				    DOT_RESOURCE_LEN, filp->f_pos,
-				    ntohl(entry->cnid) | HFS_CAP_RDIR)) {
+				    ntohl(entry->cnid) | HFS_CAP_RDIR, DT_UNKNOWN)) {
 				return 0;
 			}
 		}
diff -urN lfs-ref/fs/hfs/dir_dbl.c lfs/fs/hfs/dir_dbl.c
--- lfs-ref/fs/hfs/dir_dbl.c	Mon Jan 17 16:44:42 2000
+++ lfs/fs/hfs/dir_dbl.c	Thu Mar  1 16:41:28 2001
@@ -206,7 +206,7 @@
 
 	if (filp->f_pos == 0) {
 		/* Entry 0 is for "." */
-		if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
+		if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, DT_DIR)) {
 			return 0;
 		}
 		filp->f_pos = 1;
@@ -215,7 +215,7 @@
 	if (filp->f_pos == 1) {
 		/* Entry 1 is for ".." */
 		if (filldir(dirent, DOT_DOT->Name, DOT_DOT_LEN, 1,
-			    hfs_get_hl(entry->key.ParID))) {
+			    hfs_get_hl(entry->key.ParID), DT_DIR)) {
 			return 0;
 		}
 		filp->f_pos = 2;
@@ -252,7 +252,7 @@
 				    &((struct hfs_cat_key *)brec.key)->CName);
 			}
 
-			if (filldir(dirent, tmp_name, len, filp->f_pos, ino)) {
+			if (filldir(dirent, tmp_name, len, filp->f_pos, ino, DT_UNKNOWN)) {
 				hfs_cat_close(entry, &brec);
 				return 0;
 			}
@@ -266,7 +266,7 @@
 			/* In root dir last entry is for "%RootInfo" */
 			if (filldir(dirent, PCNT_ROOTINFO->Name,
 				    PCNT_ROOTINFO_LEN, filp->f_pos,
-				    ntohl(entry->cnid) | HFS_DBL_HDR)) {
+				    ntohl(entry->cnid) | HFS_DBL_HDR, DT_UNKNOWN)) {
 				return 0;
 			}
 		}
diff -urN lfs-ref/fs/hfs/dir_nat.c lfs/fs/hfs/dir_nat.c
--- lfs-ref/fs/hfs/dir_nat.c	Mon Jan 17 16:44:42 2000
+++ lfs/fs/hfs/dir_nat.c	Thu Mar  1 16:41:28 2001
@@ -231,7 +231,7 @@
 
 	if (filp->f_pos == 0) {
 		/* Entry 0 is for "." */
-		if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino)) {
+		if (filldir(dirent, DOT->Name, DOT_LEN, 0, dir->i_ino, DT_DIR)) {
 			return 0;
 		}
 		filp->f_pos = 1;
@@ -248,7 +248,7 @@
 		}
 
 		if (filldir(dirent, DOT_DOT->Name,
-			    DOT_DOT_LEN, 1, ntohl(cnid))) {
+			    DOT_DOT_LEN, 1, ntohl(cnid), DT_DIR)) {
 			return 0;
 		}
 		filp->f_pos = 2;
@@ -275,7 +275,7 @@
 				len = hfs_namein(dir, tmp_name,
 				    &((struct hfs_cat_key *)brec.key)->CName);
 				if (filldir(dirent, tmp_name, len,
-					    filp->f_pos, ino)) {
+					    filp->f_pos, ino, DT_UNKNOWN)) {
 					hfs_cat_close(entry, &brec);
 					return 0;
 				}
@@ -290,14 +290,14 @@
 			/* In normal dirs entry 2 is for ".AppleDouble" */
 			if (filldir(dirent, DOT_APPLEDOUBLE->Name,
 				    DOT_APPLEDOUBLE_LEN, filp->f_pos,
-				    ntohl(entry->cnid) | HFS_NAT_HDIR)) {
+				    ntohl(entry->cnid) | HFS_NAT_HDIR, DT_UNKNOWN)) {
 				return 0;
 			}
 		} else if (type == HFS_NAT_HDIR) {
 			/* In .AppleDouble entry 2 is for ".Parent" */
 			if (filldir(dirent, DOT_PARENT->Name,
 				    DOT_PARENT_LEN, filp->f_pos,
-				    ntohl(entry->cnid) | HFS_NAT_HDR)) {
+				    ntohl(entry->cnid) | HFS_NAT_HDR, DT_UNKNOWN)) {
 				return 0;
 			}
 		}
@@ -310,7 +310,7 @@
 		    (type == HFS_NAT_HDIR)) {
 			if (filldir(dirent, ROOTINFO->Name,
 				    ROOTINFO_LEN, filp->f_pos,
-				    ntohl(entry->cnid) | HFS_NAT_HDR)) {
+				    ntohl(entry->cnid) | HFS_NAT_HDR, DT_UNKNOWN)) {
 				return 0;
 			}
 		}
diff -urN lfs-ref/fs/hpfs/hpfs_fs.c lfs/fs/hpfs/hpfs_fs.c
--- lfs-ref/fs/hpfs/hpfs_fs.c	Mon Jan 17 16:44:42 2000
+++ lfs/fs/hpfs/hpfs_fs.c	Thu Mar  1 16:41:28 2001
@@ -1376,13 +1376,13 @@
 		break;
 
 	case 0:
-		if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino) < 0)
+		if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0)
 			break;
 		filp->f_pos = -1;
 		/* fall through */
 
 	case -1:
-		if (filldir(dirent, "..", 2, filp->f_pos, inode->i_hpfs_parent_dir) < 0)
+		if (filldir(dirent, "..", 2, filp->f_pos, inode->i_hpfs_parent_dir, DT_DIR) < 0)
 			break;
 		filp->f_pos = 1;
 		/* fall through */
@@ -1402,7 +1402,7 @@
 			else
 				ino = file_ino(de->fnode);
 			brelse4(&qbh);
-			if (filldir(dirent, tempname, namelen, old_pos, ino) < 0) {
+			if (filldir(dirent, tempname, namelen, old_pos, ino, DT_UNKNOWN) < 0) {
 				filp->f_pos = old_pos;
 				break;
 			}
diff -urN lfs-ref/fs/isofs/dir.c lfs/fs/isofs/dir.c
--- lfs-ref/fs/isofs/dir.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/isofs/dir.c	Thu Mar  1 16:41:28 2001
@@ -206,7 +206,7 @@
 
 		/* Handle the case of the '.' directory */
 		if (de->name_len[0] == 1 && de->name[0] == 0) {
-			if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino) < 0)
+			if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0)
 				break;
 			filp->f_pos += de_len;
 			continue;
@@ -217,7 +217,7 @@
 		/* Handle the case of the '..' directory */
 		if (de->name_len[0] == 1 && de->name[0] == 1) {
 			inode_number = filp->f_dentry->d_parent->d_inode->i_ino;
-			if (filldir(dirent, "..", 2, filp->f_pos, inode_number) < 0)
+			if (filldir(dirent, "..", 2, filp->f_pos, inode_number, DT_DIR) < 0)
 				break;
 			filp->f_pos += de_len;
 			continue;
@@ -261,7 +261,7 @@
 			}
 		}
 		if (len > 0) {
-			if (filldir(dirent, p, len, filp->f_pos, inode_number) < 0)
+			if (filldir(dirent, p, len, filp->f_pos, inode_number, DT_UNKNOWN) < 0)
 				break;
 		}
 		filp->f_pos += de_len;
diff -urN lfs-ref/fs/isofs/inode.c lfs/fs/isofs/inode.c
--- lfs-ref/fs/isofs/inode.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/isofs/inode.c	Thu Mar  1 16:41:28 2001
@@ -908,7 +908,8 @@
 
 int isofs_bmap(struct inode * inode,int block)
 {
-	off_t b_off, offset, size;
+	loff_t b_off;
+	unsigned offset, size;
 	struct inode *ino;
 	unsigned int firstext;
 	unsigned long nextino;
@@ -919,7 +920,7 @@
 		return 0;
 	}
 
-	b_off = block << ISOFS_BUFFER_BITS(inode);
+	b_off = (loff_t)block << ISOFS_BUFFER_BITS(inode);
 
 	/*
 	 * If we are beyond the end of this file, don't give out any
@@ -927,7 +928,7 @@
 	 */
 	if( b_off >= inode->i_size )
 	  {
-	    off_t	max_legal_read_offset;
+	    loff_t	max_legal_read_offset;
 
 	    /*
 	     * If we are *way* beyond the end of the file, print a message.
@@ -942,7 +943,7 @@
 	    if( b_off >= max_legal_read_offset )
 	      {
 
-		printk("_isofs_bmap: block>= EOF(%d, %ld)\n", block,
+		printk("_isofs_bmap: block>= EOF(%d, %Ld)\n", block,
 		       inode->i_size);
 	      }
 	    return 0;
@@ -1209,7 +1210,7 @@
 
 #ifdef DEBUG
 	printk("Get inode %x: %d %d: %d\n",inode->i_ino, block,
-	       ((int)pnt) & 0x3ff, inode->i_size);
+	       ((int)pnt) & 0x3ff, (u_long)inode->i_size);
 #endif
 
 	inode->i_mtime = inode->i_atime = inode->i_ctime =
diff -urN lfs-ref/fs/lockd/svclock.c lfs/fs/lockd/svclock.c
--- lfs-ref/fs/lockd/svclock.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/lockd/svclock.c	Thu Mar  1 16:41:28 2001
@@ -100,14 +100,18 @@
 	struct nlm_block	**head, *block;
 	struct file_lock	*fl;
 
-	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);
+	dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
+				file, lock->fl.fl_pid,
+				(long long)lock->fl.fl_start,
+				(long long)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("lockd: check f=%p pd=%d %ld-%ld ty=%d cookie=%x\n",
-				block->b_file, fl->fl_pid, fl->fl_start,
-				fl->fl_end, fl->fl_type, 
+		dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%x\n",
+				block->b_file, fl->fl_pid,
+				(long long)lock->fl.fl_start,
+				(long long)lock->fl.fl_end,
+				fl->fl_type, 
 				*(u32 *)(&block->b_call.a_args.cookie.data));
 		if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) {
 			if (remove)
@@ -293,12 +297,12 @@
 	struct inode            *inode = file->f_file.f_dentry->d_inode;
 	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,
-				lock->fl.fl_start,
-				lock->fl.fl_end,
+				(long long)lock->fl.fl_start,
+				(long long)lock->fl.fl_end,
 				wait);
 	
 	/* Checking for read only file system */
@@ -371,16 +375,18 @@
 {
 	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,
-				lock->fl.fl_start,
-				lock->fl.fl_end);
+				(long long)lock->fl.fl_start,
+				(long long)lock->fl.fl_end);
 
 	if ((fl = posix_test_lock(&file->f_file, &lock->fl)) != NULL) {
-		dprintk("lockd: conflicting lock(ty=%d, %ld-%ld)\n",
-				fl->fl_type, fl->fl_start, fl->fl_end );
+		dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
+				fl->fl_type,
+				(long long)lock->fl.fl_start,
+				(long long)lock->fl.fl_end);
 
 		conflock->caller = "somehost";	/* FIXME */
 		conflock->oh.len = 0;		/* don't return OH info */
@@ -403,12 +409,12 @@
 {
 	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,
-				lock->fl.fl_start,
-				lock->fl.fl_end);
+				(long long)lock->fl.fl_start,
+				(long long)lock->fl.fl_end);
 
 	/* First, cancel any lock that might be there */
 	nlmsvc_cancel_blocked(file, lock);
@@ -431,12 +437,12 @@
 {
 	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,
-				lock->fl.fl_start,
-				lock->fl.fl_end);
+				(long long)lock->fl.fl_start,
+				(long long)lock->fl.fl_end);
 
 	down(&file->f_sema);
 	if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL)
diff -urN lfs-ref/fs/lockd/xdr.c lfs/fs/lockd/xdr.c
--- lfs-ref/fs/lockd/xdr.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/lockd/xdr.c	Thu Mar  1 16:41:28 2001
@@ -24,7 +24,6 @@
 
 #define NLMDBG_FACILITY		NLMDBG_XDR
 #define NLM_MAXSTRLEN		1024
-#define OFFSET_MAX		LONG_MAX
 
 #define QUADLEN(len)		(((len) + 3) >> 2)
 
@@ -37,6 +36,25 @@
 static void nlm_register_stats(void);
 static void nlm_unregister_stats(void);
 
+static inline loff_t
+s32_to_loff_t(__s32 offset)
+{
+	return (loff_t)offset;
+}
+
+static inline __s32
+loff_t_to_s32(loff_t offset)
+{
+	__s32 res;
+	if (offset >= NLM_OFFSET_MAX)
+		res = NLM_OFFSET_MAX;
+	else if (offset <= -NLM_OFFSET_MAX)
+		res = -NLM_OFFSET_MAX;
+	else
+		res = offset;
+	return res;
+}
+
 /*
  * Initialization of NFS status variables
  */
@@ -157,7 +175,7 @@
 nlm_decode_lock(u32 *p, struct nlm_lock *lock)
 {
 	struct file_lock	*fl = &lock->fl;
-	int			len;
+	s32			start, len, end;
 
 	if (!(p = xdr_decode_string(p, &lock->caller, &len, NLM_MAXSTRLEN))
 	 || !(p = nlm_decode_fh(p, &lock->fh))
@@ -169,10 +187,16 @@
 	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++);
+	start = ntohl(*p++);
 	len = ntohl(*p++);
-	if (len == 0 || (fl->fl_end = fl->fl_start + len - 1) < 0)
+	end = start + len - 1;
+
+	fl->fl_start = s32_to_loff_t(start);
+
+	if (len == 0 || end < 0)
 		fl->fl_end = OFFSET_MAX;
+	else
+		fl->fl_end = s32_to_loff_t(end);
 	return p;
 }
 
@@ -183,6 +207,7 @@
 nlm_encode_lock(u32 *p, struct nlm_lock *lock)
 {
 	struct file_lock	*fl = &lock->fl;
+	__s32			start, len;
 
 	if (!(p = xdr_encode_string(p, lock->caller, -1))
 	 || !(p = nlm_encode_fh(p, &lock->fh))
@@ -193,12 +218,15 @@
 	 || (fl->fl_end > NLM_OFFSET_MAX && fl->fl_end != OFFSET_MAX))
 		return NULL;
 
-	*p++ = htonl(fl->fl_pid);
-	*p++ = htonl(fl->fl_start);
+	start = loff_t_to_s32(fl->fl_start);
 	if (fl->fl_end == OFFSET_MAX)
-		*p++ = xdr_zero;
+		len = 0;
 	else
-		*p++ = htonl(fl->fl_end - fl->fl_start + 1);
+		len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1);
+
+	*p++ = htonl(fl->fl_pid);
+	*p++ = htonl(start);
+	*p++ = htonl(len);
 
 	return p;
 }
@@ -209,6 +237,8 @@
 static u32 *
 nlm_encode_testres(u32 *p, struct nlm_res *resp)
 {
+	s32		start, len;
+
 	if (!(p = nlm_encode_cookie(p, &resp->cookie)))
 		return 0;
 	*p++ = resp->status;
@@ -223,11 +253,14 @@
 		if (!(p = xdr_encode_netobj(p, &resp->lock.oh)))
 			return 0;
 
-		*p++ = htonl(fl->fl_start);
+		start = loff_t_to_s32(fl->fl_start);
 		if (fl->fl_end == OFFSET_MAX)
-			*p++ = xdr_zero;
+			len = xdr_zero;
 		else
-			*p++ = htonl(fl->fl_end - fl->fl_start + 1);
+			len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1);
+
+		*p++ = htonl(start);
+		*p++ = htonl(len);
 	}
 
 	return p;
@@ -446,7 +479,8 @@
 	resp->status = ntohl(*p++);
 	if (resp->status == NLM_LCK_DENIED) {
 		struct file_lock	*fl = &resp->lock.fl;
-		u32			excl, len;
+		u32			excl;
+		s32			start, len, end;
 
 		memset(&resp->lock, 0, sizeof(resp->lock));
 		excl = ntohl(*p++);
@@ -456,10 +490,15 @@
 
 		fl->fl_flags = FL_POSIX;
 		fl->fl_type  = excl? F_WRLCK : F_RDLCK;
-		fl->fl_start = ntohl(*p++);
+		start = ntohl(*p++);
 		len = ntohl(*p++);
-		if (len == 0 || (fl->fl_end = fl->fl_start + len - 1) < 0)
+		end = start + len - 1;
+
+		fl->fl_start = s32_to_loff_t(start);
+		if (len == 0 || end < 0)
 			fl->fl_end = OFFSET_MAX;
+		else
+			fl->fl_end = s32_to_loff_t(end);
 	}
 	return 0;
 }
diff -urN lfs-ref/fs/lockd/xdr4.c lfs/fs/lockd/xdr4.c
--- lfs-ref/fs/lockd/xdr4.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/lockd/xdr4.c	Thu Mar  1 16:41:28 2001
@@ -23,7 +23,6 @@
 
 #define NLMDBG_FACILITY		NLMDBG_XDR
 #define NLM_MAXSTRLEN		1024
-#define OFFSET_MAX		((off_t)LONG_MAX)
 
 #define QUADLEN(len)		(((len) + 3) >> 2)
 
@@ -34,11 +33,23 @@
 
 typedef struct nlm_args	nlm_args;
 
-static inline off_t
-size_to_off_t(__s64 size)
+static inline loff_t
+s64_to_loff_t(__s64 offset)
 {
-        size = (size > (__s64)LONG_MAX) ? (off_t)LONG_MAX : (off_t) size;
-        return (size < (__s64)-LONG_MAX) ? (off_t)-LONG_MAX : (off_t) size;
+	return (loff_t)offset;
+}
+ 
+static inline s64
+loff_t_to_s64(loff_t offset)
+{
+	s64 res;
+	if (offset > NLM4_OFFSET_MAX)
+		res = NLM4_OFFSET_MAX;
+	else if (offset < -NLM4_OFFSET_MAX)
+		res = -NLM4_OFFSET_MAX;
+	else
+		res = offset;
+	return res;
 }
 
 /*
@@ -139,11 +150,12 @@
 	p = xdr_decode_hyper(p, &len);
 	end = start + len - 1;
 
-	fl->fl_start = size_to_off_t(start);
-	fl->fl_end = size_to_off_t(end);
+	fl->fl_start = s64_to_loff_t(start);
 
-	if (len == 0 || fl->fl_end < 0)
+	if (len == 0 || end < 0)
 		fl->fl_end = OFFSET_MAX;
+	else
+		fl->fl_end = s64_to_loff_t(end);
 	return p;
 }
 
@@ -154,18 +166,26 @@
 nlm4_encode_lock(u32 *p, struct nlm_lock *lock)
 {
 	struct file_lock	*fl = &lock->fl;
+	__s64			start, len;
 
 	if (!(p = xdr_encode_string(p, lock->caller, -1))
 	 || !(p = nlm4_encode_fh(p, &lock->fh))
 	 || !(p = nlm4_encode_oh(p, &lock->oh)))
 		return NULL;
 
-	*p++ = htonl(fl->fl_pid);
-	p = xdr_encode_hyper(p, fl->fl_start);
+	if (fl->fl_start > NLM4_OFFSET_MAX
+	 || (fl->fl_end > NLM4_OFFSET_MAX && fl->fl_end != OFFSET_MAX))
+		return NULL;
+
+	start = loff_t_to_s64(fl->fl_start);
 	if (fl->fl_end == OFFSET_MAX)
-		p = xdr_encode_hyper(p, 0);
+		len = 0;
 	else
-		p = xdr_encode_hyper(p, fl->fl_end - fl->fl_start + 1);
+		len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1);
+
+	*p++ = htonl(fl->fl_pid);
+	p = xdr_encode_hyper(p, start);
+	p = xdr_encode_hyper(p, len);
 
 	return p;
 }
@@ -176,6 +196,7 @@
 static u32 *
 nlm4_encode_testres(u32 *p, struct nlm_res *resp)
 {
+	s64		start, len;
 
 	dprintk("xdr: before encode_testres (p %p resp %p)\n", p, resp);
 	if (!(p = nlm4_encode_cookie(p, &resp->cookie)))
@@ -192,14 +213,17 @@
 		if (!(p = xdr_encode_netobj(p, &resp->lock.oh)))
 			return 0;
 
-		p = xdr_encode_hyper(p, fl->fl_start);
+		start = loff_t_to_s64(fl->fl_start);
 		if (fl->fl_end == OFFSET_MAX)
-			p = xdr_encode_hyper(p, 0);
+			len = 0;
 		else
-			p = xdr_encode_hyper(p, fl->fl_end - fl->fl_start + 1);
-		dprintk("xdr: encode_testres (status %d pid %d type %d start %ld end %ld)\n", resp->status, fl->fl_pid, fl->fl_type, fl->fl_start,  fl->fl_end);
-
-
+			len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1);
+		
+		p = xdr_encode_hyper(p, start);
+		p = xdr_encode_hyper(p, len);
+		dprintk("xdr: encode_testres (status %d pid %d type %d start %Ld end %Ld)\n",
+			resp->status, fl->fl_pid, fl->fl_type,
+			fl->fl_start, fl->fl_end);
 	}
 
 	dprintk("xdr: after encode_testres (p %p resp %p)\n", p, resp);
@@ -435,10 +459,11 @@
 		p = xdr_decode_hyper(p, &len);
 		end = start + len - 1;
 
-		fl->fl_start = size_to_off_t(start);
-		fl->fl_end = size_to_off_t(end);
-		if (len == 0 || fl->fl_end < 0)
+		fl->fl_start = s64_to_loff_t(start);
+		if (len == 0 || end < 0)
 			fl->fl_end = OFFSET_MAX;
+		else
+			fl->fl_end = s64_to_loff_t(end);
 	}
 	return 0;
 }
diff -urN lfs-ref/fs/locks.c lfs/fs/locks.c
--- lfs-ref/fs/locks.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/locks.c	Thu Mar  1 16:41:28 2001
@@ -111,12 +111,12 @@
 
 #include <asm/uaccess.h>
 
-#define OFFSET_MAX	((off_t)LONG_MAX)	/* 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,
+static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
 			       struct flock *l);
+static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
+				 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);
@@ -344,9 +344,10 @@
 	if (!filp->f_dentry || !filp->f_dentry->d_inode || !filp->f_op)
 		goto out_putf;
 
-	if (!posix_make_lock(filp, &file_lock, &flock))
+	if ((error = flock_to_posix_lock(filp, &file_lock, &flock)))
 		goto out_putf;
 
+	error = -EINVAL;
 	if (filp->f_op->lock) {
 		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
 		if (error < 0)
@@ -363,6 +364,18 @@
 	flock.l_type = F_UNLCK;
 	if (fl != NULL) {
 		flock.l_pid = fl->fl_pid;
+#if BITS_PER_LONG == 32
+		/*
+		 * Make sure we can represent the posix lock via
+		 * legacy 32bit flock.
+		 */
+		error = -EOVERFLOW;
+		if (fl->fl_start > OFFT_OFFSET_MAX)
+			goto out_putf;
+		if ((fl->fl_end != OFFSET_MAX)
+		    && (fl->fl_end > OFFT_OFFSET_MAX))
+			goto out_putf;
+#endif
 		flock.l_start = fl->fl_start;
 		flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
 			fl->fl_end - fl->fl_start + 1;
@@ -424,8 +437,7 @@
 		goto out_putf;
 	}
 
-	error = -EINVAL;
-	if (!posix_make_lock(filp, &file_lock, &flock))
+	if ((error = flock_to_posix_lock(filp, &file_lock, &flock)))
 		goto out_putf;
 	
 	error = -EBADF;
@@ -475,6 +487,169 @@
 	return error;
 }
 
+#if BITS_PER_LONG == 32
+/* 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;
+	if (copy_from_user(&flock, l, sizeof(flock)))
+		goto out;
+	error = -EINVAL;
+	if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK))
+		goto out;
+
+	error = -EBADF;
+	filp = fget(fd);
+	if (!filp)
+		goto out;
+
+	error = -EINVAL;
+	if (!filp->f_dentry || !filp->f_dentry->d_inode || !filp->f_op)
+		goto out_putf;
+
+	if (!flock64_to_posix_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;
+		else if (error == LOCK_USE_CLNT)
+		  /* Bypass for NFS with no locking - 2.0.36 compat */
+		  fl = posix_test_lock(filp, &file_lock);
+		else
+		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &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;
+	}
+	error = -EFAULT;
+	if (!copy_to_user(l, &flock, sizeof(flock)))
+		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_setlk64(unsigned int fd, unsigned int cmd, struct flock64 *l)
+{
+	struct file *filp;
+	struct file_lock file_lock;
+	struct flock64 flock;
+	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(&flock, l, sizeof(flock)))
+		goto out;
+
+	/* 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;
+	if (!filp->f_op)
+		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 (!flock64_to_posix_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_SETLKW64);
+
+out_putf:
+	fput(filp);
+out:
+	return error;
+}
+#endif /* BITS_PER_LONG == 32 */
+
 /*
  * This function is called when the file is being removed
  * from the task's fd array.
@@ -655,10 +830,70 @@
 /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
  * style lock.
  */
-static int posix_make_lock(struct file *filp, struct file_lock *fl,
-			   struct flock *l)
+static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
+			       struct flock *l)
+{
+	loff_t start;
+	int ret = -EINVAL;
+
+	memset(fl, 0, sizeof(*fl));
+	
+	fl->fl_flags = FL_POSIX;
+
+	switch (l->l_type) {
+	case F_RDLCK:
+	case F_WRLCK:
+	case F_UNLCK:
+		fl->fl_type = l->l_type;
+		break;
+	default:
+		goto out;
+	}
+
+	switch (l->l_whence) {
+	case 0: /*SEEK_SET*/
+		start = 0;
+		break;
+	case 1: /*SEEK_CUR*/
+		start = filp->f_pos;
+		break;
+	case 2: /*SEEK_END*/
+		start = filp->f_dentry->d_inode->i_size;
+		break;
+	default:
+		goto out;
+	}
+
+	if (((start += l->l_start) < 0) || (l->l_len < 0))
+		goto out;
+	fl->fl_end = start + l->l_len - 1;
+	if (l->l_len > 0 && fl->fl_end < 0)
+		goto out;
+	fl->fl_start = start;	/* we record the absolute position */
+	if (l->l_len != 0) {
+		start = fl->fl_end;
+	} else {
+		start = fl->fl_start;
+		fl->fl_end = OFFSET_MAX;
+	}
+	ret = -EOVERFLOW;
+	if (start > OFFT_OFFSET_MAX)
+		goto out;
+	
+	fl->fl_file = filp;
+	fl->fl_owner = current->files;
+	fl->fl_pid = current->pid;
+
+	ret = 0;
+ out:
+	return ret;
+}
+
+#if BITS_PER_LONG == 32
+static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
+				 struct flock64 *l)
 {
-	off_t start;
+	loff_t start;
 
 	memset(fl, 0, sizeof(*fl));
 	
@@ -703,6 +938,7 @@
 
 	return (1);
 }
+#endif
 
 /* Verify a call to flock() and fill in a file_lock structure with
  * an appropriate FLOCK lock.
@@ -1217,7 +1453,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);
@@ -1281,6 +1517,3 @@
 		*start = buffer;
 	return (q - buffer);
 }
-
-
-
diff -urN lfs-ref/fs/minix/dir.c lfs/fs/minix/dir.c
--- lfs-ref/fs/minix/dir.c	Mon Jan 17 16:44:42 2000
+++ lfs/fs/minix/dir.c	Thu Mar  1 16:41:28 2001
@@ -82,7 +82,7 @@
 			de = (struct minix_dir_entry *) (offset + bh->b_data);
 			if (de->inode) {
 				int size = strnlen(de->name, info->s_namelen);
-				if (filldir(dirent, de->name, size, filp->f_pos, de->inode) < 0) {
+				if (filldir(dirent, de->name, size, filp->f_pos, de->inode, DT_UNKNOWN) < 0) {
 					brelse(bh);
 					return 0;
 				}
diff -urN lfs-ref/fs/minix/file.c lfs/fs/minix/file.c
--- lfs-ref/fs/minix/file.c	Mon Jan 17 16:44:42 2000
+++ lfs/fs/minix/file.c	Thu Mar  1 16:41:28 2001
@@ -70,8 +70,8 @@
 				size_t count, loff_t *ppos)
 {
 	struct inode * inode = filp->f_dentry->d_inode;
-	off_t pos;
-	ssize_t written, c;
+	loff_t pos;
+	ssize_t written, c, m;
 	struct buffer_head * bh;
 	char * p;
 
@@ -87,15 +87,34 @@
 		pos = inode->i_size;
 	else
 		pos = *ppos;
+
+	/* L-F-S spec 2.2.1.27: */
+	if (!(filp->f_flags & O_LARGEFILE)) {
+		if (pos >= 0x7fffffffULL) /* pos@2G forbidden */
+			return -EFBIG;
+
+		if (pos + count > 0x7fffffffULL)
+			/* Write only until end of allowed region */
+			count = 0x7fffffffULL - pos;
+	}
+	/* MINIX i-node file-size can't exceed 4G-1 */
+	/* With 1k blocks and triple indirection MINIX can have files
+	   up to 16 GB in size -- filesystem maximum is then 4G*1k = 4T */
+	if (pos >= 0xffffffffULL)
+		return -EFBIG; /* Absolutely too much! */
+	if ((pos + count) >= 0x100000000ULL) /* too much to write! */
+		count = 0xffffffffULL - pos;
+
 	written = 0;
 	while (written < count) {
-		bh = minix_getblk(inode,pos/BLOCK_SIZE,1);
+		bh = minix_getblk(inode, pos >> BLOCK_SIZE_BITS, 1);
 		if (!bh) {
 			if (!written)
 				written = -ENOSPC;
 			break;
 		}
-		c = BLOCK_SIZE - (pos % BLOCK_SIZE);
+		m = pos & (BLOCK_SIZE - 1);
+		c = BLOCK_SIZE - m;
 		if (c > count-written)
 			c = count-written;
 		if (c != BLOCK_SIZE && !buffer_uptodate(bh)) {
@@ -108,7 +127,7 @@
 				break;
 			}
 		}
-		p = (pos % BLOCK_SIZE) + bh->b_data;
+		p = bh->b_data + m;
 		c -= copy_from_user(p,buf,c);
 		if (!c) {
 			brelse(bh);
diff -urN lfs-ref/fs/ncpfs/dir.c lfs/fs/ncpfs/dir.c
--- lfs-ref/fs/ncpfs/dir.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/ncpfs/dir.c	Thu Mar  1 16:41:28 2001
@@ -449,14 +449,14 @@
 	result = 0;
 	if (filp->f_pos == 0) {
 		ncp_invalid_dir_cache(inode);
-		if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0) {
+		if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) {
 			goto finished;
 		}
 		filp->f_pos = 1;
 	}
 	if (filp->f_pos == 1) {
 		if (filldir(dirent, "..", 2, 1,
-				dentry->d_parent->d_inode->i_ino) < 0) {
+				dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
 			goto finished;
 		}
 		filp->f_pos = 2;
@@ -537,7 +537,7 @@
 			ino = ncp_invent_inos(1);
 
 		if (filldir(dirent, entry->i.entryName, entry->i.nameLen,
-			    entry->f_pos, ino) < 0) {
+			    entry->f_pos, ino, DT_UNKNOWN) < 0) {
 			break;
 		}
 		if ((inode->i_dev != c_dev)
diff -urN lfs-ref/fs/ncpfs/file.c lfs/fs/ncpfs/file.c
--- lfs-ref/fs/ncpfs/file.c	Mon Dec 11 16:58:00 2000
+++ lfs/fs/ncpfs/file.c	Thu Mar  1 16:41:28 2001
@@ -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"
@@ -161,7 +162,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),
@@ -201,7 +202,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;
@@ -238,12 +239,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)) {
diff -urN lfs-ref/fs/ncpfs/inode.c lfs/fs/ncpfs/inode.c
--- lfs-ref/fs/ncpfs/inode.c	Tue Jun 13 03:48:14 2000
+++ lfs/fs/ncpfs/inode.c	Thu Mar  1 16:41:28 2001
@@ -131,7 +131,7 @@
 	}
 	inode->i_blocks = 0;
 	if ((inode->i_size)&&(inode->i_blksize)) {
-		inode->i_blocks = (inode->i_size-1)/(inode->i_blksize)+1;
+		inode->i_blocks = ((inode->i_size-1) >> fslog2(inode->i_blksize)) +1;
 	}
 
 	inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(nwi->modifyTime),
@@ -201,8 +201,7 @@
 
 	inode->i_blocks = 0;
 	if ((inode->i_blksize != 0) && (inode->i_size != 0)) {
-		inode->i_blocks =
-		    (inode->i_size - 1) / inode->i_blksize + 1;
+		inode->i_blocks = ((inode->i_size - 1) >> fslog2(inode->i_blksize)) + 1;
 	}
 
 	inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(nwi->modifyTime),
diff -urN lfs-ref/fs/nfs/dir.c lfs/fs/nfs/dir.c
--- lfs-ref/fs/nfs/dir.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfs/dir.c	Thu Mar  1 16:41:28 2001
@@ -137,7 +137,7 @@
 	int		plus = NFS_USE_READDIRPLUS(inode);
 	int		error;
 
-	dfprintk(VFS, "NFS: nfs_readdir_filler() reading cookie %Lu into page %lu.\n", (long long)desc->entry->cookie, page->offset);
+	dfprintk(VFS, "NFS: nfs_readdir_filler() reading cookie %Lu into page %Lu.\n", (long long)desc->entry->cookie, (long long) nfs_page_offset(page));
 
  again:
 	error = NFS_PROTO(inode)->readdir(inode, cred,
@@ -158,7 +158,7 @@
 	 * Note: assumes we have exclusive access to this inode either
 	 *	 throught inode->i_sem or some other mechanism.
 	 */
-	if (page->offset == 0)
+	if (page_index(page) == 0)
 		invalidate_inode_pages(inode);
 	nfs_unlock_page(page);
 	return 0;
@@ -294,7 +294,7 @@
 		 *	 retrieving the current dirent on the server */
 		fileid = nfs_fileid_to_ino_t(entry->ino);
 		res = filldir(dirent, entry->name, entry->len, 
-			      entry->prev_cookie, fileid);
+			      entry->prev_cookie, fileid, DT_UNKNOWN);
 		if (res < 0)
 			break;
 		file->f_pos = desc->target = entry->cookie;
diff -urN lfs-ref/fs/nfs/file.c lfs/fs/nfs/file.c
--- lfs-ref/fs/nfs/file.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfs/file.c	Thu Mar  1 16:41:28 2001
@@ -164,6 +164,9 @@
 
 static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
 {
+	if (!NFS_PROTO(file->f_dentry->d_inode)->bigfiles &&
+	    page_index(page) > (0x7fffffff>>PAGE_SHIFT))
+		return -EFBIG;
 	return nfs_flush_incompatible(file, page);
 }
 
@@ -232,10 +235,10 @@
 	struct inode * inode = 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);
+			(long long)fl->fl_start, (long long)fl->fl_end);
 
 	if (!inode)
 		return -EINVAL;
diff -urN lfs-ref/fs/nfs/inode.c lfs/fs/nfs/inode.c
--- lfs-ref/fs/nfs/inode.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfs/inode.c	Thu Mar  1 16:41:28 2001
@@ -636,7 +636,7 @@
 		 * Preset the size and mtime, as there's no need
 		 * to invalidate the caches.
 		 */
-		inode->i_size  = nfs_size_to_off_t(fattr->size);
+		inode->i_size  = nfs_size_to_loff_t(fattr->size);
 		inode->i_mtime = nfs_time_to_secs(fattr->mtime);
 		inode->i_atime = nfs_time_to_secs(fattr->atime);
 		inode->i_ctime = nfs_time_to_secs(fattr->ctime);
@@ -771,6 +771,11 @@
 	if (!S_ISREG(inode->i_mode))
 		attr->ia_valid &= ~ATTR_SIZE;
 
+	error = -EFBIG;
+	if ((attr->ia_valid & ATTR_SIZE) && !NFS_PROTO(inode)->bigfiles && 
+	    attr->ia_size > 0x7fffffff)
+		goto out; 
+
 	error = nfs_wb_all(inode);
 	if (error < 0)
 		goto out;
@@ -844,6 +849,10 @@
 	struct rpc_cred	*cred = rpcauth_lookupcred(auth, 0);
 
 	filp->private_data = cred;
+
+	if (!NFS_PROTO(filp->f_dentry->d_inode)->bigfiles)     
+		filp->f_flags &= ~O_LARGEFILE; 
+
 	return 0;
 }
 
@@ -925,8 +934,8 @@
 int
 nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
 {
-	off_t		new_size, new_isize;
-	__u64		new_mtime;
+	__u64		new_size, new_mtime;
+	loff_t		new_isize;
 	int		invalid = 0;
 	int		error = -EIO;
 
@@ -973,7 +982,7 @@
 
  	new_mtime = fattr->mtime;
 	new_size = fattr->size;
- 	new_isize = nfs_size_to_off_t(fattr->size);
+ 	new_isize = nfs_size_to_loff_t(fattr->size);
 
 	error = 0;
 
diff -urN lfs-ref/fs/nfs/nfs3proc.c lfs/fs/nfs/nfs3proc.c
--- lfs-ref/fs/nfs/nfs3proc.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfs/nfs3proc.c	Thu Mar  1 16:41:28 2001
@@ -145,7 +145,7 @@
 static int
 nfs3_proc_read(struct inode *inode, struct rpc_cred *cred,
 	       struct nfs_fattr *fattr, int flags,
-	       unsigned long offset, unsigned int count,
+	       loff_t offset, unsigned int count,
 	       void *buffer, int *eofp)
 {
 	struct nfs_readargs	arg = { NFS_FH(inode), offset, count, 1,
@@ -155,7 +155,7 @@
 	struct rpc_message	msg = { NFS3PROC_READ, &arg, &res, cred };
 	int			status;
 
-	dprintk("NFS call  read %d @ %ld\n", count, offset);
+	dprintk("NFS call  read %d @ %Ld\n", count, (long long) offset);
 	fattr->valid = 0;
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
 	dprintk("NFS reply read: %d\n", status);
@@ -166,7 +166,7 @@
 static int
 nfs3_proc_write(struct inode *inode, struct rpc_cred *cred,
 		struct nfs_fattr *fattr, int flags,
-		unsigned long offset, unsigned int count,
+		loff_t offset, unsigned int count,
 		void *buffer, struct nfs_writeverf *verf)
 {
 	struct nfs_writeargs	arg = { NFS_FH(inode), offset, count,
@@ -177,7 +177,7 @@
 	struct rpc_message	msg = { NFS3PROC_WRITE, &arg, &res, cred };
 	int			status, rpcflags = 0;
 
-	dprintk("NFS call  write %d @ %ld\n", count, offset);
+	dprintk("NFS call  write %d @ %Ld\n", count, (long long) offset);
 	fattr->valid = 0;
 	if (flags & NFS_RW_SWAP)
 		rpcflags |= NFS_RPC_SWAPFLAGS;
@@ -517,4 +517,6 @@
 	nfs3_proc_statfs,
 
 	nfs3_decode_dirent,
+
+	1, 
 };
diff -urN lfs-ref/fs/nfs/proc.c lfs/fs/nfs/proc.c
--- lfs-ref/fs/nfs/proc.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfs/proc.c	Thu Mar  1 16:41:28 2001
@@ -134,7 +134,7 @@
 
 static int
 nfs_proc_read(struct inode *inode, struct rpc_cred *cred, fattr *fattr,
-	      int flags, unsigned long offset, unsigned int count,
+	      int flags, loff_t offset, unsigned int count,
 	      void *buffer, int *eofp)
 {
 	struct nfs_readargs	arg = { NFS_FH(inode), offset, count, 1,
@@ -144,7 +144,7 @@
 	struct rpc_message	msg = { NFSPROC_READ, &arg, &res, cred };
 	int			status;
 
-	dprintk("NFS call  read %d @ %ld\n", count, offset);
+	dprintk("NFS call  read %d @ %Ld\n", count, (long long) offset);
 	fattr->valid = 0;
 	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
 
@@ -155,7 +155,7 @@
 
 static int
 nfs_proc_write(struct inode *inode, struct rpc_cred *cred, fattr *fattr,
-	       int how, unsigned long offset, unsigned int count,
+	       int how, loff_t offset, unsigned int count,
 	       void *buffer, struct nfs_writeverf *verf)
 {
 	struct nfs_writeargs	arg = {NFS_FH(inode), offset, count,
@@ -166,7 +166,7 @@
 	struct rpc_message	msg = { NFSPROC_WRITE, &arg, &res, cred };
 	int			status, flags = 0;
 
-	dprintk("NFS call  write %d @ %ld\n", count, offset);
+	dprintk("NFS call  write %d @ %Ld\n", count, (long long) offset);
 	fattr->valid = 0;
 	if (how & NFS_RW_SWAP)
 		flags |= NFS_RPC_SWAPFLAGS;
@@ -407,4 +407,5 @@
        nfs_proc_mknod,
        nfs_proc_statfs,
        nfs_decode_dirent,
+       0,
 };
diff -urN lfs-ref/fs/nfs/read.c lfs/fs/nfs/read.c
--- lfs-ref/fs/nfs/read.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfs/read.c	Thu Mar  1 16:41:28 2001
@@ -91,7 +91,7 @@
 {
 	struct rpc_cred	*cred = NULL;
 	struct nfs_fattr fattr;
-	unsigned long	offset = nfs_page_offset(page);
+	loff_t		offset = nfs_page_offset(page);
 	char		*buffer = (char *) page_address(page);
 	int		rsize = NFS_SERVER(inode)->rsize;
 	int		result, refresh = 0;
@@ -112,10 +112,10 @@
 		if ((chunk = rsize) > count)
 			chunk = count;
 
-		dprintk("NFS: nfs_proc_read(%s, (%x/%Ld), %ld, %d, %p)\n",
+		dprintk("NFS: nfs_proc_read(%s, (%x/%Ld), %Ld, %d, %p)\n",
 			NFS_SERVER(inode)->hostname,
 			inode->i_dev, (long long)NFS_FILEID(inode),
-			offset, chunk, buffer);
+			(long long) offset, chunk, buffer);
 
 		result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags,
 						offset, chunk, buffer, &eof);
@@ -439,11 +439,11 @@
 			set_bit(PG_error, &page->flags);
 		nfs_unlock_page(page);
 
-		dprintk("NFS: read (%x/%Ld %d@%ld)\n",
+		dprintk("NFS: read (%x/%Ld %d@%Ld)\n",
 			req->wb_inode->i_dev,
 			(long long)NFS_FILEID(req->wb_inode),
                         req->wb_bytes,
-                        (nfs_page_offset(page) + req->wb_offset));
+                        (long long)(nfs_page_offset(page) + req->wb_offset));
 		nfs_unlock_request(req);
 		nfs_release_request(req);
 	}
@@ -475,8 +475,8 @@
 	else
 		inode = file->f_dentry->d_inode;
 
-	dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",
-		page, PAGE_CACHE_SIZE, page->offset);
+	dprintk("NFS: nfs_readpage (%p %ld@%Lu)\n",
+		page, PAGE_CACHE_SIZE, (long long) nfs_page_offset(page));
 
 	/*
 	 * Try to flush any pending writes to the file
diff -urN lfs-ref/fs/nfs/write.c lfs/fs/nfs/write.c
--- lfs-ref/fs/nfs/write.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfs/write.c	Thu Mar  1 16:41:28 2001
@@ -144,7 +144,7 @@
  */
 static int
 nfs_writepage_sync(struct file *file, struct inode *inode, struct page *page,
-		   unsigned long offset, unsigned int count)
+		   unsigned int offset, unsigned int count)
 {
 	struct rpc_cred	*cred = NULL;
 	unsigned int	wsize = NFS_SERVER(inode)->wsize;
@@ -152,16 +152,17 @@
 	u8		*buffer;
 	struct nfs_fattr fattr;
 	struct nfs_writeverf verifier;
+	loff_t		base;
 
 	if (file)
 		cred = nfs_file_cred(file);
 
-	dprintk("NFS:      nfs_writepage_sync(%x/%Ld %d@%ld)\n",
+	dprintk("NFS:      nfs_writepage_sync(%x/%Ld %d@%Ld)\n",
 		inode->i_dev, (long long)NFS_FILEID(inode),
-		count, nfs_page_offset(page) + offset);
+		count, (long long) (nfs_page_offset(page) + offset));
 
 	buffer = (u8 *) page_address(page) + offset;
-	offset += nfs_page_offset(page);
+	base = nfs_page_offset(page) + offset;
 
 	flags = ((IS_SWAPFILE(inode)) ? NFS_RW_SWAP : 0) | NFS_RW_SYNC;
 
@@ -170,7 +171,7 @@
 			wsize = count;
 
 		result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags,
-						 offset, wsize, buffer,
+						 base, wsize, buffer,
 						 &verifier);
 		nfs_write_attributes(inode, &fattr);
 
@@ -184,15 +185,15 @@
 			wsize, result);
 		refresh = 1;
 		buffer  += wsize;
-		offset  += wsize;
+		base	+= 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 (base > inode->i_size)
+			inode->i_size = base;
 	} while (count);
 
 io_error:
@@ -213,9 +214,9 @@
 		inode = page->inode;
 	else
 		inode = file->f_dentry->d_inode;
-	if (page->offset >= inode->i_size)
+	if (nfs_page_offset(page) >= inode->i_size)
 		return -EIO;
-	if (page->offset + offset > inode->i_size)
+	if (nfs_page_offset(page) + offset > inode->i_size)
 		offset = inode->i_size & (PAGE_CACHE_SIZE-1);
 	return nfs_writepage_sync(file, inode, page, 0, offset);
 }
@@ -228,7 +229,7 @@
 region_locked(struct inode *inode, struct nfs_page *req)
 {
 	struct file_lock	*fl;
-	unsigned long		rqstart, rqend;
+	loff_t			rqstart, rqend;
 
 	/* Don't optimize writes if we don't use NLM */
 	if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
@@ -895,9 +896,9 @@
 	struct nfs_page	*req;
 	int		status = 0;
 
-	dprintk("NFS:      nfs_updatepage(%s/%s %d@%ld, sync=%d)\n",
+	dprintk("NFS:      nfs_updatepage(%s/%s %d@%Ld, sync=%d)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		count, nfs_page_offset(page)+offset, sync);
+		count, (long long) (nfs_page_offset(page)+offset), sync);
 
 	/*
 	 * If wsize is smaller than page size, update and write
@@ -947,8 +948,8 @@
 	}
 	nfs_release_request(req);
 done:
-        dprintk("NFS:      nfs_updatepage returns %d (isize %ld)\n",
-                                                status, inode->i_size);
+        dprintk("NFS:      nfs_updatepage returns %d (isize %Ld)\n",
+                                                status, (long long) inode->i_size);
 	if (status < 0)
 		clear_bit(PG_uptodate, &page->flags);
 	return status;
@@ -1193,18 +1194,18 @@
 {
 	struct nfs_page		*req;
 	struct inode		*inode;
-	unsigned long		start, end, len;
+	loff_t			start, end, len;
 
 	/* Set up the RPC argument and reply structs
 	 * NB: take care not to mess about with data->commit et al. */
 
 	end = 0;
-	start = ~0;
+	start = NFS_OFFSET_MAX;
 	req = nfs_list_entry(head->next);
 	inode = req->wb_inode;
 	while (!list_empty(head)) {
 		struct nfs_page	*req;
-		unsigned long	rqstart, rqend;
+		loff_t	rqstart, rqend;
 		req = nfs_list_entry(head->next);
 		nfs_list_remove_request(req);
 		nfs_list_add_request(req, &data->pages);
@@ -1220,7 +1221,7 @@
 	data->args.fh     = NFS_FH(inode);
 	data->args.offset = start;
 	len = end - start;
-	if (end >= inode->i_size || len > (~((u32)0) >> 1))
+	if (end >= inode->i_size || len < 0 || len > (~((u32)0) >> 1))
 		len = 0;
 	data->res.count   = data->args.count = (u32)len;
 	data->res.fattr   = &data->fattr;
@@ -1298,11 +1299,11 @@
 		req = nfs_list_entry(data->pages.next);
 		nfs_list_remove_request(req);
 
-		dprintk("NFS: commit (%x/%Ld %d@%ld)",
+		dprintk("NFS: commit (%x/%Ld %d@%Ld)",
 			req->wb_inode->i_dev,
 			(long long)NFS_FILEID(req->wb_inode),
 			req->wb_bytes,
-			nfs_page_offset(req->wb_page) + req->wb_offset);
+			(long long) (nfs_page_offset(req->wb_page) + req->wb_offset));
 		if (task->tk_status < 0) {
 			if (req->wb_file)
 				req->wb_file->f_error = task->tk_status;
diff -urN lfs-ref/fs/nfsd/nfs3xdr.c lfs/fs/nfsd/nfs3xdr.c
--- lfs-ref/fs/nfsd/nfs3xdr.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfsd/nfs3xdr.c	Thu Mar  1 16:41:28 2001
@@ -131,9 +131,9 @@
 		iap->ia_valid |= ATTR_SIZE;
 		p = xdr_decode_hyper(p, &newsize);
 		if (newsize <= NFS_OFFSET_MAX)
-			iap->ia_size = (u32) newsize;
+			iap->ia_size = newsize;
 		else
-			iap->ia_size = ~(size_t) 0;
+			iap->ia_size = NFS_OFFSET_MAX;
 	}
 	if ((tmp = ntohl(*p++)) == 1) {	/* set to server time */
 		iap->ia_valid |= ATTR_ATIME;
@@ -678,11 +678,6 @@
 	if (name == 0)
 		return 0;
 
-	/*
-	dprintk("encode_entry(%.*s @%ld%s)\n",
-		namlen, name, (long) offset, plus? " plus" : "");
-	 */
-
 	/* truncate filename if too long */
 	if (namlen > NFS3_MAXNAMLEN)
 		namlen = NFS3_MAXNAMLEN;
@@ -727,14 +722,14 @@
 
 int
 nfs3svc_encode_entry(struct readdir_cd *cd, const char *name,
-				int namlen, off_t offset, ino_t ino)
+				int namlen, off_t offset, ino_t ino, unsigned int d_type)
 {
 	return encode_entry(cd, name, namlen, offset, ino, 0);
 }
 
 int
 nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name,
-				int namlen, off_t offset, ino_t ino)
+				int namlen, off_t offset, ino_t ino, unsigned int d_type)
 {
 	return encode_entry(cd, name, namlen, offset, ino, 1);
 }
diff -urN lfs-ref/fs/nfsd/nfsfh.c lfs/fs/nfsd/nfsfh.c
--- lfs-ref/fs/nfsd/nfsfh.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfsd/nfsfh.c	Thu Mar  1 16:41:28 2001
@@ -41,7 +41,7 @@
  * the name matching the specified inode number.
  */
 static int filldir_one(void * __buf, const char * name, int len,
-			off_t pos, ino_t ino)
+			off_t pos, ino_t ino, unsigned int d_type)
 {
 	struct nfsd_getdents_callback *buf = __buf;
 	struct qstr *qs = buf->name;
diff -urN lfs-ref/fs/nfsd/nfssvc.c lfs/fs/nfsd/nfssvc.c
--- lfs-ref/fs/nfsd/nfssvc.c	Mon Dec 11 16:58:01 2000
+++ lfs/fs/nfsd/nfssvc.c	Thu Mar  1 16:41:28 2001
@@ -115,6 +115,7 @@
 	current->session = 1;
 	current->pgrp = 1;
 	current->fs->umask = 0;
+	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
 	/* Count active threads */
 	atomic_inc(&nfsd_active);
diff -urN lfs-ref/fs/nfsd/nfsxdr.c lfs/fs/nfsd/nfsxdr.c
--- lfs-ref/fs/nfsd/nfsxdr.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfsd/nfsxdr.c	Thu Mar  1 16:41:28 2001
@@ -394,7 +394,7 @@
 
 int
 nfssvc_encode_entry(struct readdir_cd *cd, const char *name,
-					int namlen, off_t offset, ino_t ino)
+		    int namlen, off_t offset, ino_t ino, unsigned int d_type)
 {
 	u32	*p = cd->buffer;
 	int	buflen, slen;
diff -urN lfs-ref/fs/nfsd/vfs.c lfs/fs/nfsd/vfs.c
--- lfs-ref/fs/nfsd/vfs.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/nfsd/vfs.c	Thu Mar  1 16:41:28 2001
@@ -513,11 +513,11 @@
 	filp->f_count = 1;
 	filp->f_dentry = dentry;
 	if (access & MAY_WRITE) {
-		filp->f_flags = O_WRONLY;
+		filp->f_flags = O_WRONLY | O_LARGEFILE;
 		filp->f_mode  = FMODE_WRITE;
 		DQUOT_INIT(inode);
 	} else {
-		filp->f_flags = O_RDONLY;
+		filp->f_flags = O_RDONLY | O_LARGEFILE;
 		filp->f_mode  = FMODE_READ;
 	}
 
@@ -658,8 +658,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,
-			file.f_ralen, file.f_rawin);
+			(u_long)file.f_reada, (u_long)file.f_ramax,
+			(u_long)file.f_raend, (u_long)file.f_ralen,
+			(u_long)file.f_rawin);
 		ra->p_reada = file.f_reada;
 		ra->p_ramax = file.f_ramax;
 		ra->p_raend = file.f_raend;
diff -urN lfs-ref/fs/ntfs/fs.c lfs/fs/ntfs/fs.c
--- lfs-ref/fs/ntfs/fs.c	Tue Sep  5 02:28:49 2000
+++ lfs/fs/ntfs/fs.c	Thu Mar  1 16:41:28 2001
@@ -199,7 +199,7 @@
 	/* filldir expects an off_t rather than an loff_t.
 	   Hope we don't have more than 65535 index records */
 	error=nf->filldir(nf->dirent,nf->name,nf->namelen,
-			(nf->ph<<16)|nf->pl,inum);
+			(nf->ph<<16)|nf->pl,inum,DT_UNKNOWN);
 	ntfs_free(nf->name);
 	/* Linux filldir errors are negative, other errors positive */
 	return error;
@@ -225,11 +225,11 @@
 	if(cb.ph==0xFFFF){
 		/* FIXME: Maybe we can return those with the previous call */
 		switch(cb.pl){
-		case 0: filldir(dirent,".",1,filp->f_pos,dir->i_ino);
+		case 0: filldir(dirent,".",1,filp->f_pos,dir->i_ino,DT_DIR);
 			filp->f_pos=0xFFFF0001;
 			return 0;
 			/* FIXME: parent directory */
-		case 1: filldir(dirent,"..",2,filp->f_pos,0);
+		case 1: filldir(dirent,"..",2,filp->f_pos,0,DT_DIR);
 			filp->f_pos=0xFFFF0002;
 			return 0;
 		}
@@ -822,6 +822,7 @@
 	struct statfs fs;
 	struct inode *mft;
 	ntfs_volume *vol;
+	ntfs_u64 size;
 	int error;
 
 	ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");
@@ -830,16 +831,17 @@
 	fs.f_type=NTFS_SUPER_MAGIC;
 	fs.f_bsize=vol->clustersize;
 
-	error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &fs.f_blocks );
+	error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &size );
 	if( error )
 		return -error;
+	fs.f_blocks = size;
 	fs.f_bfree=ntfs_get_free_cluster_count(vol->bitmap);
 	fs.f_bavail=fs.f_bfree;
 
 	/* Number of files is limited by free space only, so we lie here */
 	fs.f_ffree=0;
 	mft=iget(sb,FILE_MFT);
-	fs.f_files=mft->i_size/vol->mft_recordsize;
+	fs.f_files = (long)mft->i_size / vol->mft_recordsize;
 	iput(mft);
 
 	/* should be read from volume */
diff -urN lfs-ref/fs/ntfs/super.c lfs/fs/ntfs/super.c
--- lfs-ref/fs/ntfs/super.c	Mon Dec 11 16:58:03 2000
+++ lfs/fs/ntfs/super.c	Thu Mar  1 16:41:28 2001
@@ -304,7 +304,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;
@@ -325,9 +325,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 -urN lfs-ref/fs/ntfs/super.h lfs/fs/ntfs/super.h
--- lfs-ref/fs/ntfs/super.h	Mon Jan 17 16:44:42 2000
+++ lfs/fs/ntfs/super.h	Thu Mar  1 16:41:28 2001
@@ -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 -urN lfs-ref/fs/open.c lfs/fs/open.c
--- lfs-ref/fs/open.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/open.c	Thu Mar  1 16:41:28 2001
@@ -12,7 +12,7 @@
 
 #include <asm/uaccess.h>
 
-asmlinkage int sys_statfs(const char * path, struct statfs * buf)
+asmlinkage long sys_statfs(const char * path, struct statfs * buf)
 {
 	struct dentry * dentry;
 	int error;
@@ -34,7 +34,7 @@
 	return error;
 }
 
-asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
+asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf)
 {
 	struct file * file;
 	struct inode * inode;
@@ -63,15 +63,16 @@
 	return error;
 }
 
-int do_truncate(struct dentry *dentry, unsigned long length)
+int 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)
-		return -EINVAL;
+	/* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
+	error = -EINVAL;
+	if (length < 0)
+		goto out;
 
 	fs_down(&inode->i_sem);
 	newattrs.ia_size = length;
@@ -84,10 +85,11 @@
 			inode->i_op->truncate(inode);
 	}
 	fs_up(&inode->i_sem);
+out:
 	return error;
 }
 
-asmlinkage int sys_truncate(const char * path, unsigned long length)
+static inline long do_sys_truncate(const char * path, loff_t length)
 {
 	struct dentry * dentry;
 	struct inode * inode;
@@ -136,7 +138,12 @@
 	return error;
 }
 
-asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length)
+asmlinkage long sys_truncate(const char * path, unsigned long length)
+{
+	return do_sys_truncate(path, length);
+}
+
+static inline long do_sys_ftruncate(unsigned int fd, loff_t length)
 {
 	struct inode * inode;
 	struct dentry *dentry;
@@ -171,6 +178,24 @@
 	return error;
 }
 
+asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
+{
+	return do_sys_ftruncate(fd, length);
+}
+
+/* LFS versions of truncate are only needed on 32 bit machines */
+#if BITS_PER_LONG == 32
+asmlinkage long sys_truncate64(const char * path, loff_t length)
+{
+	return do_sys_truncate(path, length);
+}
+
+asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
+{
+	return do_sys_ftruncate(fd, length);
+}
+#endif
+
 #ifndef __alpha__
 
 /*
@@ -184,7 +209,7 @@
  * must be owner or have write permission.
  * Else, update from *times, must be owner or super user.
  */
-asmlinkage int sys_utime(char * filename, struct utimbuf * times)
+asmlinkage long sys_utime(char * filename, struct utimbuf * times)
 {
 	int error;
 	struct dentry * dentry;
@@ -232,7 +257,7 @@
  * must be owner or have write permission.
  * Else, update from *times, must be owner or super user.
  */
-asmlinkage int sys_utimes(char * filename, struct timeval * utimes)
+asmlinkage long sys_utimes(char * filename, struct timeval * utimes)
 {
 	int error;
 	struct dentry * dentry;
@@ -278,7 +303,7 @@
  * We do this by temporarily clearing all FS-related capabilities and
  * switching the fsuid/fsgid around to the real ones.
  */
-asmlinkage int sys_access(const char * filename, int mode)
+asmlinkage long sys_access(const char * filename, int mode)
 {
 	struct dentry * dentry;
 	int old_fsuid, old_fsgid;
@@ -319,7 +344,7 @@
 	return res;
 }
 
-asmlinkage int sys_chdir(const char * filename)
+asmlinkage long sys_chdir(const char * filename)
 {
 	int error;
 	struct inode *inode;
@@ -354,7 +379,7 @@
 	return error;
 }
 
-asmlinkage int sys_fchdir(unsigned int fd)
+asmlinkage long sys_fchdir(unsigned int fd)
 {
 	struct file *file;
 	struct dentry *dentry;
@@ -391,7 +416,7 @@
 	return error;
 }
 
-asmlinkage int sys_chroot(const char * filename)
+asmlinkage long sys_chroot(const char * filename)
 {
 	int error;
 	struct inode *inode;
@@ -431,7 +456,7 @@
 	return error;
 }
 
-asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
+asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
 {
 	struct inode * inode;
 	struct dentry * dentry;
@@ -469,7 +494,7 @@
 	return err;
 }
 
-asmlinkage int sys_chmod(const char * filename, mode_t mode)
+asmlinkage long sys_chmod(const char * filename, mode_t mode)
 {
 	struct dentry * dentry;
 	struct inode * inode;
@@ -565,7 +590,7 @@
 	return error;
 }
 
-asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
+asmlinkage long sys_chown(const char * filename, uid_t user, gid_t group)
 {
 	struct dentry * dentry;
 	int error;
@@ -582,7 +607,7 @@
 	return error;
 }
 
-asmlinkage int sys_lchown(const char * filename, uid_t user, gid_t group)
+asmlinkage long sys_lchown(const char * filename, uid_t user, gid_t group)
 {
 	struct dentry * dentry;
 	int error;
@@ -600,7 +625,7 @@
 }
 
 
-asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
+asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
 {
 	struct dentry * dentry;
 	struct file * file;
@@ -645,6 +670,9 @@
 	f = get_empty_filp();
 	if (!f)
 		goto out;
+#if BITS_PER_LONG != 32
+	flags |= O_LARGEFILE;
+#endif
 	f->f_flags = flag = flags;
 	f->f_mode = (flag+1) & O_ACCMODE;
 	if (f->f_mode)
@@ -783,7 +811,7 @@
  * For backward compatibility?  Maybe this should be moved
  * into arch/i386 instead?
  */
-asmlinkage int sys_creat(const char * pathname, int mode)
+asmlinkage long sys_creat(const char * pathname, int mode)
 {
 	return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
 }
@@ -856,7 +884,7 @@
  * This routine simulates a hangup on the tty, to arrange that users
  * are given clean terminals at login time.
  */
-asmlinkage int sys_vhangup(void)
+asmlinkage long sys_vhangup(void)
 {
 	int ret = -EPERM;
 
diff -urN lfs-ref/fs/proc/array.c lfs/fs/proc/array.c
--- lfs-ref/fs/proc/array.c	Thu Mar  1 16:41:11 2001
+++ lfs/fs/proc/array.c	Thu Mar  1 16:41:28 2001
@@ -1173,11 +1173,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 %016Lx %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
diff -urN lfs-ref/fs/proc/fd.c lfs/fs/proc/fd.c
--- lfs-ref/fs/proc/fd.c	Thu Mar  1 16:41:11 2001
+++ lfs/fs/proc/fd.c	Thu Mar  1 16:41:28 2001
@@ -146,7 +146,7 @@
 		ino = inode->i_ino;
 		if (fd)
 			ino = (ino & 0xffff0000) | PROC_PID_INO;
-		if (filldir(dirent, "..", fd+1, fd, ino) < 0)
+		if (filldir(dirent, "..", fd+1, fd, ino, DT_DIR) < 0)
 			goto out;
 	}
 
@@ -176,7 +176,7 @@
 		read_unlock(&tasklist_lock);
 
 		ino = (pid << 16) + PROC_PID_FD_DIR + fd;
-		if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
+		if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0)
 			goto out;
 
 		read_lock(&tasklist_lock);
diff -urN lfs-ref/fs/proc/openpromfs.c lfs/fs/proc/openpromfs.c
--- lfs-ref/fs/proc/openpromfs.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/proc/openpromfs.c	Thu Mar  1 16:41:28 2001
@@ -846,14 +846,14 @@
 	i = filp->f_pos;
 	switch (i) {
 	case 0:
-		if (filldir(dirent, ".", 1, i, ino) < 0) return 0;
+		if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) return 0;
 		i++;
 		filp->f_pos++;
 		/* fall thru */
 	case 1:
 		if (filldir(dirent, "..", 2, i, 
 			(NODE(ino).parent == 0xffff) ? 
-			PROC_ROOT_INO : NODE2INO(NODE(ino).parent)) < 0) 
+			PROC_ROOT_INO : NODE2INO(NODE(ino).parent), DT_DIR) < 0) 
 			return 0;
 		i++;
 		filp->f_pos++;
@@ -869,14 +869,14 @@
 			if (prom_getname (nodes[node].node, buffer, 128) < 0)
 				return 0;
 			if (filldir(dirent, buffer, strlen(buffer),
-				    filp->f_pos, NODE2INO(node)) < 0)
+				    filp->f_pos, NODE2INO(node), DT_DIR) < 0)
 				return 0;
 			filp->f_pos++;
 			node = nodes[node].next;
 		}
 		j = NODEP2INO(NODE(ino).first_prop);
 		if (!i) {
-			if (filldir(dirent, ".node", 5, filp->f_pos, j) < 0)
+			if (filldir(dirent, ".node", 5, filp->f_pos, j, DT_REG) < 0)
 				return 0;
 			filp->f_pos++;
 		} else
@@ -887,7 +887,7 @@
 				if (alias_names [i]) {
 					if (filldir (dirent, alias_names [i], 
 						strlen (alias_names [i]), 
-						filp->f_pos, j) < 0) return 0;
+						filp->f_pos, j, DT_REG) < 0) return 0;
 					filp->f_pos++;
 				}
 			}
@@ -899,7 +899,7 @@
 				if (i) i--;
 				else {
 					if (filldir(dirent, p, strlen(p),
-						    filp->f_pos, j) < 0)
+						    filp->f_pos, j, DT_REG) < 0)
 						return 0;
 					filp->f_pos++;
 				}
@@ -911,7 +911,7 @@
 				else {
 					if (filldir(dirent, d->name,
 						    strlen(d->name),
-						    filp->f_pos, d->inode) < 0)
+						    filp->f_pos, d->inode, d->mode >> 12) < 0)
 						return 0;
 					filp->f_pos++;
 				}
diff -urN lfs-ref/fs/proc/root.c lfs/fs/proc/root.c
--- lfs-ref/fs/proc/root.c	Thu Mar  1 16:41:11 2001
+++ lfs/fs/proc/root.c	Thu Mar  1 16:41:28 2001
@@ -890,13 +890,13 @@
 	i = filp->f_pos;
 	switch (i) {
 		case 0:
-			if (filldir(dirent, ".", 1, i, ino) < 0)
+			if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
 				return 0;
 			i++;
 			filp->f_pos++;
 			/* fall through */
 		case 1:
-			if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0)
+			if (filldir(dirent, "..", 2, i, de->parent->low_ino, DT_DIR) < 0)
 				return 0;
 			i++;
 			filp->f_pos++;
@@ -915,7 +915,7 @@
 			}
 
 			do {
-				if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0)
+				if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino, de->mode >> 12) < 0)
 					return 0;
 				filp->f_pos++;
 				de = de->next;
@@ -982,7 +982,7 @@
 			pid /= 10;
 		} while (pid);
 
-		if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino) < 0)
+		if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0)
 			break;
 		filp->f_pos++;
 	}
diff -urN lfs-ref/fs/qnx4/dir.c lfs/fs/qnx4/dir.c
--- lfs-ref/fs/qnx4/dir.c	Thu May  4 13:00:40 2000
+++ lfs/fs/qnx4/dir.c	Thu Mar  1 16:41:28 2001
@@ -61,7 +61,7 @@
 							QNX4_INODES_PER_BLOCK +
 							le->dl_inode_ndx;
 					}
-					if (filldir(dirent, de->di_fname, size, filp->f_pos, ino) < 0) {
+					if (filldir(dirent, de->di_fname, size, filp->f_pos, ino, DT_UNKNOWN) < 0) {
 						brelse(bh);
 						return 0;
 					}
diff -urN lfs-ref/fs/read_write.c lfs/fs/read_write.c
--- lfs-ref/fs/read_write.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/read_write.c	Thu Mar  1 16:41:28 2001
@@ -48,7 +48,7 @@
 
 asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
 {
-	off_t retval;
+	off_t retval, oldpos;
 	struct file * file;
 	struct dentry * dentry;
 	struct inode * inode;
@@ -62,9 +62,19 @@
 	if (!(dentry = file->f_dentry) ||
 	    !(inode = dentry->d_inode))
 		goto out_putf;
+	oldpos = file->f_pos;
 	retval = -EINVAL;
 	if (origin <= 2)
 		retval = llseek(file, offset, origin);
+
+	/* Demand L-F-S compliance only from normal files,
+	   thus raw devices can do whatever they please.. */
+	if (!(file->f_flags & O_LARGEFILE) &&
+	    retval >= 0 && S_ISREG(inode->i_mode) &&
+	    file->f_pos > 0x7fffffff) {
+		file->f_pos = oldpos;
+		retval = -EOVERFLOW;
+	}
 out_putf:
 	fput(file);
 bad:
@@ -81,7 +91,7 @@
 	struct file * file;
 	struct dentry * dentry;
 	struct inode * inode;
-	loff_t offset;
+	loff_t offset, oldpos;
 
 	lock_kernel();
 	retval = -EBADF;
@@ -96,6 +106,7 @@
 	if (origin > 2)
 		goto out_putf;
 
+	oldpos = file->f_pos;
 	offset = llseek(file, ((loff_t) offset_high << 32) | offset_low,
 			origin);
 
@@ -105,6 +116,14 @@
 		if (!copy_to_user(result, &offset, sizeof(offset)))
 			retval = 0;
 	}
+	if (!(file->f_flags & O_LARGEFILE) && S_ISREG(inode->i_mode) &&
+	    file->f_pos > 0x7fffffff) {
+		/* 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;
+	}
 out_putf:
 	fput(file);
 bad:
@@ -335,6 +354,7 @@
 	ssize_t ret;
 	struct file * file;
 	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+	struct inode * inode;
 
 	lock_kernel();
 
@@ -342,10 +362,13 @@
 	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);
+
+	ret = locks_verify_area(FLOCK_VERIFY_READ, inode, file, pos, count);
 	if (ret)
 		goto out;
 	ret = -EINVAL;
@@ -367,6 +390,7 @@
 	ssize_t ret;
 	struct file * file;
 	ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
+	struct inode * inode;
 
 	lock_kernel();
 
@@ -376,8 +400,10 @@
 		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);
+
+	inode = file->f_dentry->d_inode;
+
+	ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, pos, count);
 	if (ret)
 		goto out;
 	ret = -EINVAL;
@@ -386,9 +412,9 @@
 	if (pos < 0)
 		goto out;
 
-	fs_down(&file->f_dentry->d_inode->i_sem);
+	fs_down(&inode->i_sem);
 	ret = write(file, buf, count, &pos);
-	fs_up(&file->f_dentry->d_inode->i_sem);
+	fs_up(&inode->i_sem);
 
 out:
 	fput(file);
diff -urN lfs-ref/fs/readdir.c lfs/fs/readdir.c
--- lfs-ref/fs/readdir.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/readdir.c	Thu Mar  1 16:41:45 2001
@@ -36,7 +36,7 @@
 	int count;
 };
 
-static int fillonedir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+static int fillonedir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct readdir_callback * buf = (struct readdir_callback *) __buf;
 	struct old_linux_dirent * dirent;
@@ -118,7 +118,7 @@
 	int error;
 };
 
-static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino, unsigned int d_type)
 {
 	struct linux_dirent * dirent;
 	struct getdents_callback * buf = (struct getdents_callback *) __buf;
@@ -187,6 +187,123 @@
 	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;
+}
+
+
+/*
+ * And even better one including d_type field and 64bit d_ino and d_off.
+ */
+struct linux_dirent64 {
+	u64		d_ino;
+	s64		d_off;
+	unsigned short	d_reclen;
+	unsigned char	d_type;
+	char		d_name[0];
+};
+
+#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
+
+struct getdents_callback64 {
+	struct linux_dirent64 * current_dir;
+	struct linux_dirent64 * previous;
+	int count;
+	int error;
+};
+
+static int filldir64(void * __buf, const char * name, int namlen, off_t offset,
+		     ino_t ino, unsigned int d_type)
+{
+	struct linux_dirent64 * dirent, d;
+	struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
+	int reclen = ROUND_UP64(NAME_OFFSET(dirent) + namlen + 1);
+
+	buf->error = -EINVAL;	/* only used if we fail.. */
+	if (reclen > buf->count)
+		return -EINVAL;
+	dirent = buf->previous;
+	if (dirent) {
+#if BITS_PER_LONG < 64
+		d.d_off = offset;
+		copy_to_user(&dirent->d_off, &d.d_off, sizeof(d.d_off));
+#else
+		put_user(offset, &dirent->d_off);
+#endif
+	}
+	dirent = buf->current_dir;
+	buf->previous = dirent;
+	memset(&d, 0, NAME_OFFSET(&d));
+	d.d_ino = ino;
+	d.d_reclen = reclen;
+	d.d_type = d_type;
+	copy_to_user(dirent, &d, NAME_OFFSET(&d));
+	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 int sys_getdents64(unsigned int fd, void * dirent, unsigned int count)
+{
+	struct file * file;
+	struct dentry * dentry;
+	struct inode * inode;
+	struct linux_dirent64 * lastdirent;
+	struct getdents_callback64 buf;
+	int error;
+
+	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) {
+#if BITS_PER_LONG < 64
+		s64 d_off;
+		d_off = file->f_pos;
+		copy_to_user(&lastdirent->d_off, &d_off, sizeof(d_off));
+#else
+		put_user(file->f_pos, &lastdirent->d_off);
+#endif
 		error = count - buf.count;
 	}
 
diff -urN lfs-ref/fs/romfs/inode.c lfs/fs/romfs/inode.c
--- lfs-ref/fs/romfs/inode.c	Thu May  4 13:00:40 2000
+++ lfs/fs/romfs/inode.c	Thu Mar  1 16:41:28 2001
@@ -258,6 +258,10 @@
 	return res;
 }
 
+static unsigned char romfs_dtype_table[] = {
+	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_SOCK, DT_FIFO
+};
+
 static int
 romfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
@@ -302,7 +306,8 @@
 		nextfh = ntohl(ri.next);
 		if ((nextfh & ROMFH_TYPE) == ROMFH_HRD)
 			ino = ntohl(ri.spec);
-		if (filldir(dirent, fsname, j, offset, ino) < 0) {
+		if (filldir(dirent, fsname, j, offset, ino,
+			    romfs_dtype_table[nextfh & ROMFH_TYPE]) < 0) {
 			return stored;
 		}
 		stored++;
@@ -396,7 +401,7 @@
 	buf = page_address(page);
 	clear_bit(PG_uptodate, &page->flags);
 	clear_bit(PG_error, &page->flags);
-	offset = page->offset;
+	offset = pgoff2loff(page->index);
 	if (offset < inode->i_size) {
 		avail = inode->i_size-offset;
 		readlen = min(avail, PAGE_SIZE);
diff -urN lfs-ref/fs/smbfs/cache.c lfs/fs/smbfs/cache.c
--- lfs-ref/fs/smbfs/cache.c	Tue Sep  5 02:28:49 2000
+++ lfs/fs/smbfs/cache.c	Thu Mar  1 16:41:28 2001
@@ -40,7 +40,7 @@
 	struct cache_head * cachep;
 
 	VERBOSE("finding cache for %s/%s\n", DENTRY_PATH(dentry));
-	cachep = (struct cache_head *) get_cached_page(inode, 0, 1);
+	cachep = (struct cache_head *) get_cached_page(inode, ulong2pgoff(0), 1);
 	if (!cachep)
 		goto out;
 	if (cachep->valid)
@@ -61,9 +61,10 @@
 				PARANOIA("cache %s/%s has existing block!\n",
 					 DENTRY_PATH(dentry));
 #endif
-			offset = PAGE_SIZE + (i << PAGE_SHIFT);
-			block = (struct cache_block *) get_cached_page(inode,
-								offset, 0);
+			/* byte_offset = PAGE_SIZE + (i << PAGE_SHIFT); */
+			/*    --> page_offset = 1 + i  */ 
+			block = (struct cache_block *)
+				get_cached_page(inode, ulong2pgoff(i+1), 0);
 			if (!block)
 				goto out;
 			index->block = block;
@@ -128,7 +129,7 @@
 	struct inode * inode = get_cache_inode(cachep);
 	struct cache_index * index;
 	struct cache_block * block;
-	unsigned long page_off;
+	pgoff_t page_off;
 	unsigned int nent, offset, len = entry->len;
 	unsigned int needed = len + sizeof(struct cache_entry);
 
@@ -180,14 +181,15 @@
 	 */
 get_block:
 	cachep->pages++;
-	page_off = PAGE_SIZE + (cachep->idx << PAGE_SHIFT);
+	/* page_byte_off = PAGE_SIZE + (cachep->idx << PAGE_SHIFT); */
+	page_off = ulong2pgoff(1 + cachep->idx);
 	block = (struct cache_block *) get_cached_page(inode, page_off, 1);
 	if (block)
 	{
 		index->block = block;
 		index->space = PAGE_SIZE;
 		VERBOSE("inode=%p, pages=%d, block at %ld\n",
-			inode, cachep->pages, page_off);
+			inode, cachep->pages, (u_long)pgoff2loff(page_off));
 		goto add_entry;
 	}
 	/*
diff -urN lfs-ref/fs/smbfs/dir.c lfs/fs/smbfs/dir.c
--- lfs-ref/fs/smbfs/dir.c	Mon Dec 11 16:58:03 2000
+++ lfs/fs/smbfs/dir.c	Thu Mar  1 16:41:28 2001
@@ -91,12 +91,12 @@
 	switch ((unsigned int) filp->f_pos)
 	{
 	case 0:
-		if (filldir(dirent, ".", 1, 0, dir->i_ino) < 0)
+		if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
 			goto out;
 		filp->f_pos = 1;
 	case 1:
 		if (filldir(dirent, "..", 2, 1,
-				dentry->d_parent->d_inode->i_ino) < 0)
+				dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
 			goto out;
 		filp->f_pos = 2;
 	}
@@ -151,7 +151,7 @@
 		}
 
 		if (filldir(dirent, entry->name, entry->len, 
-				    filp->f_pos, entry->ino) < 0)
+				    filp->f_pos, entry->ino, DT_UNKNOWN) < 0)
 			break;
 		filp->f_pos += 1;
 	}
diff -urN lfs-ref/fs/smbfs/file.c lfs/fs/smbfs/file.c
--- lfs-ref/fs/smbfs/file.c	Tue Sep  5 02:28:49 2000
+++ lfs/fs/smbfs/file.c	Thu Mar  1 16:41:28 2001
@@ -15,6 +15,7 @@
 #include <linux/mm.h>
 #include <linux/malloc.h>
 #include <linux/pagemap.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -47,15 +48,15 @@
 smb_readpage_sync(struct dentry *dentry, struct page *page)
 {
 	char *buffer = (char *) page_address(page);
-	unsigned long offset = page->offset;
+	loff_t loffset = pgoff2loff(page->index);
 	int rsize = smb_get_rsize(server_from_dentry(dentry));
 	int count = PAGE_SIZE;
 	int result;
 
 	clear_bit(PG_error, &page->flags);
 
-	VERBOSE("file %s/%s, count=%d@%ld, rsize=%d\n",
-		DENTRY_PATH(dentry), count, offset, rsize);
+	VERBOSE("file %s/%s, count=%d@%Ld, rsize=%d\n",
+		DENTRY_PATH(dentry), count, loffset, rsize);
 	result = smb_open(dentry, SMB_O_RDONLY);
 	if (result < 0)
 	{
@@ -68,12 +69,12 @@
 		if (count < rsize)
 			rsize = count;
 
-		result = smb_proc_read(dentry, offset, rsize, buffer);
+		result = smb_proc_read(dentry, loffset, rsize, buffer);
 		if (result < 0)
 			goto io_error;
 
 		count -= result;
-		offset += result;
+		loffset += result;
 		buffer += result;
 		dentry->d_inode->i_atime = CURRENT_TIME;
 		if (result < rsize)
@@ -113,23 +114,36 @@
  * 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;
+	loff_t loffset = pgoff2loff(page->index) + offset;
+
+	VERBOSE("file %s/%s, count=%d@%Ld, wsize=%d\n",
+		DENTRY_PATH(dentry), count, loffset, wsize);
 
-	offset += page->offset;
-	VERBOSE("file %s/%s, count=%d@%ld, wsize=%d\n",
-		DENTRY_PATH(dentry), count, offset, wsize);
+	if (!(file->f_flags & O_LARGEFILE)) {
+		if (loffset >= 0x7fffffffULL)
+			return -EFBIG;
+		if (loffset + count > 0x7fffffffULL)
+			count = 0x7fffffff - loffset;
+	}
+
+	if (loffset >= 0xffffffffULL) /* 4G-1 ???  Or 2G-1 ??? */
+		return -EFBIG;
+	if ((loffset + count) > 0xffffffffULL)
+		count = 0xffffffffULL - 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?? */
@@ -138,29 +152,27 @@
 			printk(KERN_DEBUG "short write, wsize=%d, result=%d\n",
 			       wsize, result);
 #endif
-		buffer += wsize;
-		offset += wsize;
+		buffer  += wsize;
+		loffset += wsize;
 		written += wsize;
-		count -= 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;
 }
 
 /*
- * Write a page to the server. This will be used for NFS swapping only
- * (for now), and we currently do this synchronously only.
+ * Write a page to the server.
  */
 static int
 smb_writepage(struct file *file, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	int 	result;
 
 #ifdef SMBFS_PARANOIA
@@ -169,7 +181,7 @@
 #endif
 	set_bit(PG_locked, &page->flags);
 	atomic_inc(&page->count);
-	result = smb_writepage_sync(dentry, page, 0, PAGE_SIZE);
+	result = smb_writepage_sync(file, page, 0, PAGE_SIZE);
 	smb_unlock_page(page);
 	free_page(page_address(page));
 	return result;
@@ -180,10 +192,10 @@
 {
 	struct dentry *dentry = file->f_dentry;
 
-	DEBUG1("(%s/%s %d@%ld, sync=%d)\n",
-	       DENTRY_PATH(dentry), count, page->offset+offset, sync);
+	DEBUG1("(%s/%s %d@%Ld, sync=%d)\n",
+	       DENTRY_PATH(dentry), count, pgoff2loff(page->index)+offset, sync);
 
-	return smb_writepage_sync(dentry, page, offset, count);
+	return smb_writepage_sync(file, page, offset, count);
 }
 
 static ssize_t
@@ -192,8 +204,8 @@
 	struct dentry * dentry = file->f_dentry;
 	ssize_t	status;
 
-	VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry),
-		(unsigned long) count, (unsigned long) *ppos);
+	VERBOSE("file %s/%s, count=%lu@%Lu\n", DENTRY_PATH(dentry),
+		(unsigned long) count, *ppos);
 
 	status = smb_revalidate_inode(dentry);
 	if (status)
@@ -242,8 +254,8 @@
 	struct dentry * dentry = file->f_dentry;
 	ssize_t	result;
 
-	VERBOSE("file %s/%s, count=%lu@%lu, pages=%ld\n", DENTRY_PATH(dentry),
-		(unsigned long) count, (unsigned long) *ppos,
+	VERBOSE("file %s/%s, count=%lu@%Lu, pages=%ld\n", DENTRY_PATH(dentry),
+		(unsigned long) count, *ppos,
 		dentry->d_inode->i_nrpages);
 
 	result = smb_revalidate_inode(dentry);
@@ -261,8 +273,8 @@
 	if (count > 0)
 	{
 		result = generic_file_write(file, buf, count, ppos);
-		VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
-			(long) file->f_pos, dentry->d_inode->i_size,
+		VERBOSE("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);
 	}
 out:
diff -urN lfs-ref/fs/smbfs/proc.c lfs/fs/smbfs/proc.c
--- lfs-ref/fs/smbfs/proc.c	Thu Mar  1 16:38:54 2001
+++ lfs/fs/smbfs/proc.c	Thu Mar  1 16:41:28 2001
@@ -1086,13 +1086,16 @@
    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;
 	unsigned char *buf;
 	int result;
 
+	if (offset > 0xffffffff)
+		return -EIO;
+
 	smb_lock_server(server);
 	smb_setup_header(server, SMBread, 5, 0);
 	buf = server->packet;
@@ -1135,13 +1138,16 @@
 }
 
 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;
 
-	VERBOSE("file %s/%s, count=%d@%ld, packet_size=%d\n",
+	if (offset > 0xffffffff)
+		return -EIO;
+
+	VERBOSE("file %s/%s, count=%d@%Ld, packet_size=%d\n",
 		DENTRY_PATH(dentry), count, offset, server->packet_size);
 
 	smb_lock_server(server);
diff -urN lfs-ref/fs/stat.c lfs/fs/stat.c
--- lfs-ref/fs/stat.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/stat.c	Thu Mar  1 16:41:28 2001
@@ -48,6 +48,10 @@
 	tmp.st_uid = inode->i_uid;
 	tmp.st_gid = inode->i_gid;
 	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+#if BITS_PER_LONG == 32
+	if (inode->i_size > 0x7fffffff)
+		return -EOVERFLOW;
+#endif	
 	tmp.st_size = inode->i_size;
 	tmp.st_atime = inode->i_atime;
 	tmp.st_mtime = inode->i_mtime;
@@ -70,6 +74,10 @@
 	tmp.st_uid = inode->i_uid;
 	tmp.st_gid = inode->i_gid;
 	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+#if BITS_PER_LONG == 32
+	if (inode->i_size > 0x7fffffff)
+		return -EOVERFLOW;
+#endif	
 	tmp.st_size = inode->i_size;
 	tmp.st_atime = inode->i_atime;
 	tmp.st_mtime = inode->i_mtime;
@@ -280,3 +288,127 @@
 	unlock_kernel();
 	return error;
 }
+
+
+/* ---------- LFS-64 ----------- */
+#if !defined(__alpha__)
+
+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;
+#ifdef STAT64_HAS_BROKEN_ST_INO
+	tmp.__st_ino = inode->i_ino;
+#endif
+	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_stat64(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_lstat64(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_fstat64(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;
+}
+
+#endif /* LFS-64 */
diff -urN lfs-ref/fs/sysv/dir.c lfs/fs/sysv/dir.c
--- lfs-ref/fs/sysv/dir.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/sysv/dir.c	Thu Mar  1 16:41:28 2001
@@ -100,7 +100,7 @@
 					       inode->i_ino, (off_t) filp->f_pos, sde.inode);
 
 				i = strnlen(sde.name, SYSV_NAMELEN);
-				if (filldir(dirent, sde.name, i, filp->f_pos, sde.inode) < 0) {
+				if (filldir(dirent, sde.name, i, filp->f_pos, sde.inode, DT_UNKNOWN) < 0) {
 					brelse(bh);
 					return 0;
 				}
diff -urN lfs-ref/fs/sysv/file.c lfs/fs/sysv/file.c
--- lfs-ref/fs/sysv/file.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/sysv/file.c	Thu Mar  1 16:41:28 2001
@@ -207,7 +207,7 @@
 {
 	struct inode * inode = filp->f_dentry->d_inode;
 	struct super_block * sb = inode->i_sb;
-	off_t pos;
+	loff_t pos;
 	ssize_t written, c;
 	struct buffer_head * bh;
 	char * p;
@@ -232,6 +232,21 @@
 	else
 		pos = *ppos;
 	written = 0;
+
+	/* L-F-S spec 2.2.1.27: */
+	if (!(filp->f_flags & O_LARGEFILE)) {
+		if (pos >= 0x7fffffffULL) /* pos@2G forbidden */
+			return -EFBIG;
+
+		if (pos + count > 0x7fffffffULL)
+			/* Write only until end of allowed region */
+			count = 0x7fffffffULL - pos;
+	}
+	if (pos >= 0xffffffffULL)
+		return -EFBIG; /* Only up to 4G-1! */
+	if ((pos + count) > 0xffffffffULL)
+		count = 0xffffffffULL - pos;
+
 	while (written<count) {
 		bh = sysv_getblk (inode, pos >> sb->sv_block_size_bits, 1);
 		if (!bh) {
diff -urN lfs-ref/fs/ufs/balloc.c lfs/fs/ufs/balloc.c
--- lfs-ref/fs/ufs/balloc.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/ufs/balloc.c	Thu Mar  1 16:41:28 2001
@@ -660,9 +660,9 @@
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
 	struct ufs_cylinder_group * ucg;
-	unsigned start, length, location, result;
-	unsigned possition, fragsize, blockmap, mask;
-	unsigned swab;
+	unsigned int start, length, location, result;
+	unsigned int possition, fragsize, blockmap, mask;
+	unsigned int swab;
 	
 	UFSD(("ENTER, cg %u, goal %u, count %u\n", ucpi->c_cgx, goal, count))
 
@@ -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 -urN lfs-ref/fs/ufs/dir.c lfs/fs/ufs/dir.c
--- lfs-ref/fs/ufs/dir.c	Thu May  4 13:00:40 2000
+++ lfs/fs/ufs/dir.c	Thu Mar  1 16:41:28 2001
@@ -15,6 +15,7 @@
 
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
+#include <linux/unistd.h>
 
 #include "swab.h"
 #include "util.h"
@@ -124,11 +125,14 @@
 				 * not the directory has been modified
 				 * during the copy operation. */
 				unsigned long version = inode->i_version;
+				unsigned char d_type = DT_UNKNOWN;
 
 				UFSD(("filldir(%s,%u)\n", de->d_name, SWAB32(de->d_ino)))
 				UFSD(("namlen %u\n", ufs_get_de_namlen(de)))
+				if ((flags & UFS_DE_MASK) == UFS_DE_44BSD)
+					d_type = de->d_u.d_44.d_type;
 				error = filldir(dirent, de->d_name, ufs_get_de_namlen(de),
-						filp->f_pos, SWAB32(de->d_ino));
+						filp->f_pos, SWAB32(de->d_ino), d_type);
 				if (error)
 					break;
 				if (version != inode->i_version)
@@ -170,7 +174,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),
diff -urN lfs-ref/fs/ufs/file.c lfs/fs/ufs/file.c
--- lfs-ref/fs/ufs/file.c	Sun Apr  2 21:07:49 2000
+++ lfs/fs/ufs/file.c	Thu Mar  1 16:41:28 2001
@@ -140,7 +140,7 @@
 	loff_t *ppos )
 {
 	struct inode * inode = filp->f_dentry->d_inode;
-	__u32 pos;
+	loff_t pos;
 	long block;
 	int offset;
 	int written, c;
@@ -177,11 +177,14 @@
 			return -EINVAL;
 	}
 
-	/* Check for overflow.. */
-	if (pos > (__u32) (pos + count)) {
-		count = ~pos; /* == 0xFFFFFFFF - pos */
-		if (!count)
+	/* L-F-S spec 2.2.1.27: */
+	if (!(filp->f_flags & O_LARGEFILE)) {
+		if (pos >= 0x7fffffffULL) /* pos@2G forbidden */
 			return -EFBIG;
+
+		if (pos + count > 0x7fffffffULL)
+			/* Write only until end of allowed region */
+			count = 0x7fffffffULL - pos;
 	}
 
 	/*
diff -urN lfs-ref/fs/ufs/inode.c lfs/fs/ufs/inode.c
--- lfs-ref/fs/ufs/inode.c	Tue Jun 13 03:48:15 2000
+++ lfs/fs/ufs/inode.c	Thu Mar  1 16:41:28 2001
@@ -54,7 +54,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);
@@ -213,13 +213,14 @@
 	if (!create)
 		return NULL;
 	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-	if (limit < RLIM_INFINITY) {
+	if (limit != RLIM_INFINITY) {
 		limit >>= sb->s_blocksize_bits;
 		if (new_fragment >= limit) {
 			send_sig(SIGXFSZ, current, 0);
 			return NULL;
 		}
 	}
+
 	lastblock = ufs_fragstoblks (lastfrag);
 	lastblockoff = ufs_fragnum (lastfrag);
 	/*
@@ -321,7 +322,8 @@
 		brelse (result);
 		goto repeat;
 	}
-	if (!create || new_fragment >= (current->rlim[RLIMIT_FSIZE].rlim_cur >> sb->s_blocksize)) {
+	if (!create || (current->rlim[RLIMIT_FSIZE].rlim_cur != RLIM_INFINITY &&
+			new_fragment >= (current->rlim[RLIMIT_FSIZE].rlim_cur >> sb->s_blocksize))) {
 		brelse (bh);
 		*err = -EFBIG;
 		return NULL;
@@ -497,13 +499,10 @@
 	}
 	
 	/*
-	 * 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 = SWAB64(ufs_inode->ui_size);
 
 	inode->i_atime = SWAB32(ufs_inode->ui_atime.tv_sec);
 	inode->i_ctime = SWAB32(ufs_inode->ui_ctime.tv_sec);
@@ -516,7 +515,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))
 		inode->i_rdev = to_kdev_t(SWAB32(ufs_inode->ui_u2.ui_addr.ui_db[0]));
diff -urN lfs-ref/fs/ufs/super.c lfs/fs/ufs/super.c
--- lfs-ref/fs/ufs/super.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/ufs/super.c	Thu Mar  1 16:41:28 2001
@@ -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;
diff -urN lfs-ref/fs/ufs/truncate.c lfs/fs/ufs/truncate.c
--- lfs-ref/fs/ufs/truncate.c	Mon Jan 17 16:44:43 2000
+++ lfs/fs/ufs/truncate.c	Thu Mar  1 16:41:28 2001
@@ -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)
 
 static int ufs_trunc_direct (struct inode * inode)
 {
@@ -194,7 +194,7 @@
 }
 
 
-static int ufs_trunc_indirect (struct inode * inode, unsigned offset, u32 * p)
+static int ufs_trunc_indirect (struct inode * inode, u_long offset, u32 * p)
 {
 	struct super_block * sb;
 	struct ufs_sb_private_info * uspi;
@@ -297,7 +297,7 @@
 	struct super_block * sb;
 	struct ufs_sb_private_info * uspi;
 	struct ufs_buffer_head * dind_bh;
-	unsigned i, tmp, dindirect_block;
+	unsigned int i, tmp, dindirect_block;
 	u32 * dind;
 	int retry = 0;
 	unsigned swab;
@@ -308,8 +308,8 @@
 	swab = sb->u.ufs_sb.s_swab;
 	uspi = sb->u.ufs_sb.s_uspi;
 
-	dindirect_block = (DIRECT_BLOCK > offset) 
-		? ((DIRECT_BLOCK - offset) / uspi->s_apb) : 0;
+	dindirect_block = ((DIRECT_BLOCK > offset) ?
+			   ((DIRECT_BLOCK - offset) >> uspi->s_apbshift) : 0);
 	retry = 0;
 	
 	tmp = SWAB32(*p);
@@ -379,7 +379,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;
@@ -467,7 +467,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 -urN lfs-ref/fs/ufs/util.h lfs/fs/ufs/util.h
--- lfs-ref/fs/ufs/util.h	Sat May 20 00:06:21 2000
+++ lfs/fs/ufs/util.h	Thu Mar  1 16:41:28 2001
@@ -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 -urN lfs-ref/fs/umsdos/dir.c lfs/fs/umsdos/dir.c
--- lfs-ref/fs/umsdos/dir.c	Thu May  4 13:00:40 2000
+++ lfs/fs/umsdos/dir.c	Thu Mar  1 16:41:28 2001
@@ -90,7 +90,7 @@
 	if (d->count == 0) {
 		PRINTK ((KERN_DEBUG "dir_once :%.*s: offset %Ld\n", 
 			len, name, offset));
-		ret = d->filldir (d->dirbuf, name, len, offset, ino);
+		ret = d->filldir (d->dirbuf, name, len, offset, ino, DT_UNKNOWN);
 		d->stop = ret < 0;
 		d->count = 1;
 	}
@@ -136,7 +136,7 @@
 
 		Printk ((KERN_WARNING "umsdos_readdir_x: pseudo_root thing UMSDOS_SPECIAL_DIRFPOS\n"));
 		if (filldir (dirbuf, "DOS", 3, 
-				UMSDOS_SPECIAL_DIRFPOS, UMSDOS_ROOT_INO) == 0) {
+				UMSDOS_SPECIAL_DIRFPOS, UMSDOS_ROOT_INO, DT_DIR) == 0) {
 			filp->f_pos++;
 		}
 		goto out_end;
@@ -255,7 +255,7 @@
 		if (inode != pseudo_root &&
 		    (internal_read || !(entry.flags & UMSDOS_HIDDEN))) {
 			if (filldir (dirbuf, entry.name, entry.name_len,
-				 cur_f_pos, inode->i_ino) < 0) {
+				 cur_f_pos, inode->i_ino, DT_UNKNOWN) < 0) {
 				new_filp.f_pos = cur_f_pos;
 			}
 Printk(("umsdos_readdir_x: got %s/%s, ino=%ld\n",
diff -urN lfs-ref/fs/umsdos/rdir.c lfs/fs/umsdos/rdir.c
--- lfs-ref/fs/umsdos/rdir.c	Thu May  4 13:00:40 2000
+++ lfs/fs/umsdos/rdir.c	Thu Mar  1 16:41:28 2001
@@ -33,7 +33,8 @@
 				const char *name,
 				int name_len,
 				off_t offset,
-				ino_t ino)
+				ino_t ino,
+				unsigned int d_type)
 {
 	int ret = 0;
 	struct RDIR_FILLDIR *d = (struct RDIR_FILLDIR *) buf;
@@ -48,11 +49,11 @@
 				/* Make sure the .. entry points back to the pseudo_root */
 				ino = pseudo_root->i_ino;
 			}
-			ret = d->filldir (d->dirbuf, name, name_len, offset, ino);
+			ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN);
 		}
 	} else {
 		/* Any DOS directory */
-		ret = d->filldir (d->dirbuf, name, name_len, offset, ino);
+		ret = d->filldir (d->dirbuf, name, name_len, offset, ino, DT_UNKNOWN);
 	}
 	return ret;
 }
diff -urN lfs-ref/include/asm-i386/stat.h lfs/include/asm-i386/stat.h
--- lfs-ref/include/asm-i386/stat.h	Mon Jan 17 16:44:44 2000
+++ lfs/include/asm-i386/stat.h	Thu Mar  1 16:41:28 2001
@@ -38,4 +38,41 @@
 	unsigned long  __unused5;
 };
 
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned short	st_dev;
+	unsigned char	__pad0[10];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	__pad5;
+
+	unsigned long	st_mtime;
+	unsigned long	__pad6;
+
+	unsigned long	st_ctime;
+	unsigned long	__pad7;		/* will be high 32 bits of ctime someday */
+
+	unsigned long long	st_ino;
+};
+
 #endif
diff -urN lfs-ref/include/asm-ppc/stat.h lfs/include/asm-ppc/stat.h
--- lfs-ref/include/asm-ppc/stat.h	Mon Jan 17 16:44:45 2000
+++ lfs/include/asm-ppc/stat.h	Thu Mar  1 16:41:28 2001
@@ -37,4 +37,29 @@
 	unsigned long  	__unused5;
 };
 
+/* This matches struct stat64 in glibc2.1.
+ */
+struct stat64 {
+	unsigned long long st_dev; 	/* Device.  */
+	unsigned long long st_ino;	/* File serial number.  */
+	unsigned int st_mode;		/* File mode.  */
+	unsigned int st_nlink;		/* Link count.  */
+	unsigned int st_uid;		/* User ID of the file's owner.  */
+	unsigned int st_gid;		/* Group ID of the file's group. */
+	unsigned long long st_rdev; 	/* Device number, if device.  */
+	unsigned short int __pad2;
+	long long st_size;		/* Size of file, in bytes.  */
+	long st_blksize;		/* Optimal block size for I/O.  */
+
+	long long st_blocks;		/* Number 512-byte blocks allocated. */
+	long st_atime;			/* Time of last access.  */
+	unsigned long int __unused1;
+	long st_mtime;			/* Time of last modification.  */
+	unsigned long int __unused2;
+	long st_ctime;			/* Time of last status change.  */
+	unsigned long int __unused3;
+	unsigned long int __unused4;
+	unsigned long int __unused5;
+};
+
 #endif
diff -urN lfs-ref/include/asm-ppc/unistd.h lfs/include/asm-ppc/unistd.h
--- lfs-ref/include/asm-ppc/unistd.h	Mon Dec 11 16:58:05 2000
+++ lfs/include/asm-ppc/unistd.h	Thu Mar  1 16:41:28 2001
@@ -194,11 +194,18 @@
 #define __NR_getpmsg		187	/* some people actually want streams */
 #define __NR_putpmsg		188	/* some people actually want streams */
 #define __NR_vfork		189
-
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
 #define __NR_pciconfig_read     198
 #define __NR_pciconfig_write    199
 #define __NR_pciconfig_iobase   200
 #define __NR_multiplexer        201
+#define __NR_getdents64		202
+#define __NR_fcntl64		203
 
 #define __NR(n)	#n
 
diff -urN lfs-ref/include/linux/dirent.h lfs/include/linux/dirent.h
--- lfs-ref/include/linux/dirent.h	Tue May 25 00:49:30 1999
+++ lfs/include/linux/dirent.h	Thu Mar  1 16:41:28 2001
@@ -8,4 +8,12 @@
 	char		d_name[256]; /* We must not include limits.h! */
 };
 
+struct dirent64 {
+	__u64		d_ino;
+	__s64		d_off;
+	unsigned short	d_reclen;
+	unsigned char	d_type;
+	char		d_name[256];
+};
+
 #endif
diff -urN lfs-ref/include/linux/ext2_fs_i.h lfs/include/linux/ext2_fs_i.h
--- lfs-ref/include/linux/ext2_fs_i.h	Mon Dec 11 16:58:05 2000
+++ lfs/include/linux/ext2_fs_i.h	Thu Mar  1 16:41:28 2001
@@ -35,7 +35,6 @@
 	__u32	i_next_alloc_goal;
 	__u32	i_prealloc_block;
 	__u32	i_prealloc_count;
-	__u32	i_high_size;
 	int	i_new_inode:1;	/* Is a freshly allocated inode */
 };
 
diff -urN lfs-ref/include/linux/fs.h lfs/include/linux/fs.h
--- lfs-ref/include/linux/fs.h	Thu Mar  1 16:41:12 2001
+++ lfs/include/linux/fs.h	Thu Mar  1 16:41:28 2001
@@ -266,6 +266,25 @@
 #define buffer_page(bh)		(mem_map + MAP_NR((bh)->b_data))
 #define touch_buffer(bh)	set_bit(PG_referenced, &buffer_page(bh)->flags)
 
+/* log of base-2 for filesystem uses, in case their super-blocks
+   don't have the shift counts readily calculated.. -- presuming
+   the divisors in question are power-of-two values! */
+static int fslog2(unsigned long val) __attribute__ ((const));
+static __inline__ int fslog2(unsigned long val)
+{
+	int i;
+	for (i = 0; val != 0; ++i, val >>= 1) {
+	  if (val & 1) return i;
+	}
+	return 0;
+}
+
+static int off_t_presentable(loff_t) __attribute((const));
+static __inline__ int off_t_presentable(loff_t loff)
+{
+	return loff >= 0 && loff <= (~0UL >> 1);
+}
+
 #include <linux/pipe_fs_i.h>
 #include <linux/minix_fs_i.h>
 #include <linux/ext2_fs_i.h>
@@ -317,7 +336,7 @@
 	umode_t		ia_mode;
 	uid_t		ia_uid;
 	gid_t		ia_gid;
-	off_t		ia_size;
+	loff_t		ia_size;
 	time_t		ia_atime;
 	time_t		ia_mtime;
 	time_t		ia_ctime;
@@ -352,7 +371,7 @@
 	uid_t			i_uid;
 	gid_t			i_gid;
 	kdev_t			i_rdev;
-	off_t			i_size;
+	loff_t			i_size;
 	time_t			i_atime;
 	time_t			i_mtime;
 	time_t			i_ctime;
@@ -431,7 +450,7 @@
 	mode_t			f_mode;
 	loff_t			f_pos;
 	unsigned int 		f_count, f_flags;
-	unsigned long 		f_reada, f_ramax, f_raend, f_ralen, f_rawin;
+	loff_t			f_reada, f_ramax, f_raend, f_ralen, f_rawin;
 	struct fown_struct	f_owner;
 	unsigned int		f_uid, f_gid;
 	int			f_error;
@@ -471,8 +490,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 */
 	void (*fl_insert)(struct file_lock *);	/* lock insertion callback */
@@ -483,6 +502,9 @@
 	} fl_u;
 };
 
+#define OFFSET_MAX	((loff_t)((~0ULL)>>1))
+#define OFFT_OFFSET_MAX	((off_t)((~0UL)>>1))
+
 extern struct file_lock			*file_lock_table;
 
 #include <linux/fcntl.h>
@@ -490,6 +512,9 @@
 extern int fcntl_getlk(unsigned int fd, struct flock *l);
 extern int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l);
 
+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 id);
 extern void locks_remove_flock(struct file *);
@@ -596,12 +621,25 @@
 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
 
 /*
+ * File types
+ */
+#define DT_UNKNOWN	0
+#define DT_FIFO		1
+#define DT_CHR		2
+#define DT_DIR		4
+#define DT_BLK		6
+#define DT_REG		8
+#define DT_LNK		10
+#define DT_SOCK		12
+#define DT_WHT		14
+
+/*
  * This is the "filldir" function type, used by readdir() to let
  * the kernel specify what kind of dirent layout it wants to have.
  * This allows the kernel to read directories into kernel space or
  * to have different dirent layouts depending on the binary type.
  */
-typedef int (*filldir_t)(void *, const char *, int, off_t, ino_t);
+typedef int (*filldir_t)(void *, const char *, int, off_t, ino_t, unsigned);
 	
 struct file_operations {
 	loff_t (*llseek) (struct file *, loff_t, int);
@@ -733,7 +771,7 @@
 
 asmlinkage int sys_open(const char *, int, int);
 asmlinkage int sys_close(unsigned int);		/* yes, it's really unsigned */
-extern int do_truncate(struct dentry *, unsigned long);
+extern int do_truncate(struct dentry *, loff_t);
 
 extern struct file *filp_open(const char *, int, int);
 extern int filp_close(struct file *, fl_owner_t id);
diff -urN lfs-ref/include/linux/mm.h lfs/include/linux/mm.h
--- lfs-ref/include/linux/mm.h	Thu Mar  1 16:41:12 2001
+++ lfs/include/linux/mm.h	Thu Mar  1 16:41:28 2001
@@ -54,7 +54,7 @@
 	struct vm_area_struct **vm_pprev_share;
 
 	struct vm_operations_struct * vm_ops;
-	unsigned long vm_offset;
+	loff_t vm_offset;
 	struct file * vm_file;
 	unsigned long vm_pte;			/* shared mem */
 };
@@ -108,9 +108,46 @@
 	unsigned long (*wppage)(struct vm_area_struct * area, unsigned long address,
 		unsigned long page);
 	int (*swapout)(struct vm_area_struct *, struct page *);
-	pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
+	pte_t (*swapin)(struct vm_area_struct *, loff_t, unsigned long);
 };
 
+
+/*
+ *  pgoff_t  type -- a complex one, and its simple alternate.
+ *  The complex one has type that compiler can trap at compile
+ *  time, but the simple one does simpler code (?)
+ */
+
+#if 0
+typedef struct pgoff_t {
+  unsigned long pgoff;
+} pgoff_t;
+
+#define pgoff2ulong(pgof) ((pgof).pgoff)
+extern __inline__ pgoff_t ulong2pgoff(unsigned long ul) {
+  pgoff_t up;
+  up.pgoff = ul;
+  return up;
+}
+
+#define pgoff2loff(pgof) (((loff_t)(pgof).pgoff) << PAGE_SHIFT)
+#define loff2pgoff(loff) ulong2pgoff((loff) >> PAGE_SHIFT)
+
+#else /* Integer scalars -- simpler code.. */
+
+typedef unsigned long pgoff_t;
+
+#define pgoff2ulong(pgof) (pgof)
+#define ulong2pgoff(pgof) (pgof)
+
+#define pgoff2loff(pgof) (((loff_t)(pgof)) << PAGE_SHIFT)
+#define loff2pgoff(loff) ulong2pgoff((loff) >> PAGE_SHIFT)
+
+#endif
+
+#define PAGE_MASK_loff ((loff_t)(long)(PAGE_MASK))
+
+
 /*
  * Try to keep the most commonly accessed fields in single cache lines
  * here (16 bytes or greater).  This ordering should be particularly
@@ -119,12 +156,13 @@
  * The first line is data used in page cache lookup, the second line
  * is used for linear searches (eg. clock algorithm scans). 
  */
+
 typedef struct page {
 	/* these must be first (free area handling) */
 	struct page *next;
 	struct page *prev;
+	pgoff_t index;
 	struct inode *inode;
-	unsigned long offset;
 	struct page *next_hash;
 	atomic_t count;
 	unsigned long flags;	/* atomic flags, some possibly updated asynchronously */
@@ -299,7 +337,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);
 
@@ -319,16 +357,22 @@
 extern void exit_mmap(struct mm_struct *);
 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);
+extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+	unsigned long len, unsigned long prot,
+	unsigned long flag, unsigned long pgoff);
+
+extern unsigned long do_mmap(struct file *, unsigned long,
+			     unsigned long, unsigned long,
+			     unsigned long, unsigned long);
+
 extern int do_munmap(unsigned long, size_t);
 
 /* filemap.c */
 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 unsigned long get_cached_page(struct inode *, unsigned long, int);
+extern void truncate_inode_pages(struct inode *, loff_t);
+extern unsigned long get_cached_page(struct inode *, pgoff_t, int);
 extern void put_cached_page(unsigned long);
 
 /*
diff -urN lfs-ref/include/linux/nfs.h lfs/include/linux/nfs.h
--- lfs-ref/include/linux/nfs.h	Thu Mar  1 16:38:55 2001
+++ lfs/include/linux/nfs.h	Thu Mar  1 16:41:28 2001
@@ -78,11 +78,7 @@
 #define NFS_MNTPROC_MNT		1
 #define NFS_MNTPROC_UMNT	3
 
-/*
- * This is really a general kernel constant, but since nothing like
- * this is defined in the kernel headers, I have to do it here.
- */
-#define NFS_OFFSET_MAX		LONG_MAX
+#define NFS_OFFSET_MAX		((__s64)((~(__u64)0) >> 1))
 
 /*
  * These data types are used exlusively by the NFS client implementation.
diff -urN lfs-ref/include/linux/nfs_fs.h lfs/include/linux/nfs_fs.h
--- lfs-ref/include/linux/nfs_fs.h	Thu Mar  1 16:38:55 2001
+++ lfs/include/linux/nfs_fs.h	Thu Mar  1 16:41:28 2001
@@ -113,15 +113,15 @@
 
 
 static inline
-unsigned long nfs_page_offset(struct page *page)
+loff_t nfs_page_offset(struct page *page)
 {
-        return page->offset;
+	return ((loff_t)page->index) << PAGE_CACHE_SHIFT;
 }
 
 static inline
 unsigned long page_index(struct page *page)
 {
-	return page->offset >> PAGE_CACHE_SHIFT;
+	return page->index;
 }
 
 /*
@@ -286,6 +286,15 @@
 nfs_size_to_off_t(__u64 size)
 {
 	return (size > (__u64)LONG_MAX) ? (off_t)LONG_MAX : (off_t) size;
+}
+
+static inline loff_t
+nfs_size_to_loff_t(__u64 size)
+{
+	loff_t maxsz = (((loff_t) ULONG_MAX) << PAGE_CACHE_SHIFT) + PAGE_CACHE_SIZE - 1;
+	if (size > maxsz)
+		return maxsz;
+	return (loff_t) size;
 }
 
 static inline ino_t
diff -urN lfs-ref/include/linux/nfs_xdr.h lfs/include/linux/nfs_xdr.h
--- lfs-ref/include/linux/nfs_xdr.h	Thu Mar  1 16:38:55 2001
+++ lfs/include/linux/nfs_xdr.h	Thu Mar  1 16:41:28 2001
@@ -89,7 +89,7 @@
 #define NFS_WRITE_MAXIOV        8
 struct nfs_writeargs {
 	struct nfs_fh *		fh;
-	__u32			offset;
+	__u64			offset;
 	__u32			count;
 	enum nfs3_stable_how	stable;
 	unsigned int		nriov;
@@ -329,11 +329,11 @@
 	int	(*readlink)(struct inode *, void *buffer, unsigned int buflen);
 	int	(*read)(struct inode *, struct rpc_cred *,
 			struct nfs_fattr *,
-			int flags, unsigned long offset,
+			int flags, loff_t offset,
 			unsigned int count, void *buffer, int *eofp);
 	int	(*write)(struct inode *, struct rpc_cred *,
 			struct nfs_fattr *,
-			int flags, unsigned long offset,
+			int flags, loff_t offset,
 			unsigned int count, void *buffer,
 			struct nfs_writeverf *verfp);
 	int	(*commit)(struct inode *, struct nfs_fattr *,
@@ -361,6 +361,7 @@
 	int	(*statfs)(struct nfs_server *, struct nfs_fh *,
 			struct nfs_fsinfo *);
 	__u32 *	(*decode_dirent)(__u32 *, struct nfs_entry *, int plus);
+	int	bigfiles;
 };
 
 /*
diff -urN lfs-ref/include/linux/nfsd/nfsd.h lfs/include/linux/nfsd/nfsd.h
--- lfs-ref/include/linux/nfsd/nfsd.h	Thu Mar  1 16:38:55 2001
+++ lfs/include/linux/nfsd/nfsd.h	Thu Mar  1 16:41:28 2001
@@ -57,7 +57,7 @@
 	char			dotonly;
 };
 typedef int		(*encode_dent_fn)(struct readdir_cd *, const char *,
-						int, off_t, ino_t);
+						int, off_t, ino_t, unsigned int);
 typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
 
 /*
diff -urN lfs-ref/include/linux/nfsd/xdr.h lfs/include/linux/nfsd/xdr.h
--- lfs-ref/include/linux/nfsd/xdr.h	Tue Feb 20 20:23:46 2001
+++ lfs/include/linux/nfsd/xdr.h	Thu Mar  1 16:41:28 2001
@@ -152,7 +152,7 @@
 int nfssvc_encode_readdirres(struct svc_rqst *, u32 *, struct nfsd_readdirres *);
 
 int nfssvc_encode_entry(struct readdir_cd *, const char *name,
-				int namlen, off_t offset, ino_t ino);
+				int namlen, off_t offset, ino_t ino, unsigned int d_type);
 
 int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
 
diff -urN lfs-ref/include/linux/nfsd/xdr3.h lfs/include/linux/nfsd/xdr3.h
--- lfs-ref/include/linux/nfsd/xdr3.h	Thu Mar  1 16:38:55 2001
+++ lfs/include/linux/nfsd/xdr3.h	Thu Mar  1 16:41:28 2001
@@ -292,9 +292,9 @@
 int nfs3svc_release_fhandle2(struct svc_rqst *, u32 *,
 				struct nfsd3_fhandle_pair *);
 int nfs3svc_encode_entry(struct readdir_cd *, const char *name,
-				int namlen, off_t offset, ino_t ino);
+				int namlen, off_t offset, ino_t ino, unsigned int d_type);
 int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name,
-				int namlen, off_t offset, ino_t ino);
+				int namlen, off_t offset, ino_t ino, unsigned int d_type);
 
 
 #endif /* _LINUX_NFSD_XDR3_H */
diff -urN lfs-ref/include/linux/pagemap.h lfs/include/linux/pagemap.h
--- lfs-ref/include/linux/pagemap.h	Tue Feb 20 20:22:29 2001
+++ lfs/include/linux/pagemap.h	Thu Mar  1 16:41:28 2001
@@ -28,6 +28,7 @@
 #define PAGE_CACHE_SHIFT	PAGE_SHIFT
 #define PAGE_CACHE_SIZE		PAGE_SIZE
 #define PAGE_CACHE_MASK		PAGE_MASK
+#define PAGE_CACHE_MASK_loff	PAGE_MASK_loff
 
 #define page_cache_alloc()	__get_free_page(GFP_USER)
 #define page_cache_free(x)	free_page(x)
@@ -54,10 +55,10 @@
  * inode pointer and offsets are distributed (ie, we
  * roughly know which bits are "significant")
  */
-static inline unsigned long _page_hashfn(struct inode * inode, unsigned long offset)
+static inline unsigned long _page_hashfn(struct inode * inode, pgoff_t index)
 {
 #define i (((unsigned long) inode)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1)))
-#define o ((offset >> PAGE_SHIFT) + (offset & ~PAGE_MASK))
+#define o (index + (index >> PAGE_HASH_BITS))
 	return ((i+o) & PAGE_HASH_MASK);
 #undef i
 #undef o
@@ -65,7 +66,7 @@
 
 #define page_hash(inode,offset) (page_hash_table+_page_hashfn(inode,offset))
 
-static inline struct page * __find_page(struct inode * inode, unsigned long offset, struct page *page)
+static inline struct page * __find_page(struct inode * inode, pgoff_t index, struct page *page)
 {
 	goto inside;
 	for (;;) {
@@ -75,7 +76,7 @@
 			goto not_found;
 		if (page->inode != inode)
 			continue;
-		if (page->offset == offset)
+		if (pgoff2ulong(page->index) == pgoff2ulong(index))
 			break;
 	}
 	/* Found the page. */
@@ -85,9 +86,9 @@
 	return page;
 }
 
-static inline struct page *find_page(struct inode * inode, unsigned long offset)
+static inline struct page *find_page(struct inode * inode, pgoff_t poffset)
 {
-	return __find_page(inode, offset, *page_hash(inode, offset));
+	return __find_page(inode, poffset, *page_hash(inode, poffset));
 }
 
 static inline void remove_page_from_hash_queue(struct page * page)
@@ -110,9 +111,9 @@
 	page->pprev_hash = p;
 }
 
-static inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long offset)
+static inline void add_page_to_hash_queue(struct page * page, struct inode * inode, pgoff_t poffset)
 {
-	__add_page_to_hash_queue(page, page_hash(inode,offset));
+	__add_page_to_hash_queue(page, page_hash(inode,poffset));
 }
 
 static inline void remove_page_from_inode_queue(struct page * page)
@@ -150,8 +151,8 @@
 		__wait_on_page(page);
 }
 
-extern void update_vm_cache_conditional(struct inode *, unsigned long, const char *, int, unsigned long);
-extern void update_vm_cache(struct inode *, unsigned long, const char *, int);
+extern void update_vm_cache_conditional(struct inode *, loff_t, const char *, int, unsigned long);
+extern void update_vm_cache(struct inode *, loff_t, const char *, int);
 
 typedef int filler_t(void *, struct page*);
 
diff -urN lfs-ref/include/linux/sched.h lfs/include/linux/sched.h
--- lfs-ref/include/linux/sched.h	Thu Mar  1 16:41:11 2001
+++ lfs/include/linux/sched.h	Thu Mar  1 16:41:28 2001
@@ -316,7 +316,7 @@
 	int keep_capabilities:1;
 	struct user_struct *user;
 /* limits */
-	struct rlimit rlim[RLIM_NLIMITS];
+	struct rlimit   rlim[RLIM_NLIMITS];
 	unsigned short used_math;
 	char comm[16];
 /* file system info */
diff -urN lfs-ref/include/linux/smb_fs.h lfs/include/linux/smb_fs.h
--- lfs-ref/include/linux/smb_fs.h	Tue Feb 20 20:24:12 2001
+++ lfs/include/linux/smb_fs.h	Thu Mar  1 16:41:28 2001
@@ -121,8 +121,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 *);
diff -urN lfs-ref/include/linux/swap.h lfs/include/linux/swap.h
--- lfs-ref/include/linux/swap.h	Tue Feb 20 20:22:29 2001
+++ lfs/include/linux/swap.h	Thu Mar  1 16:41:28 2001
@@ -114,7 +114,7 @@
 extern unsigned int nr_swapfiles;
 extern struct swap_info_struct swap_info[];
 void si_swapinfo(struct sysinfo *);
-unsigned long get_swap_page(void);
+extern unsigned long  get_swap_page(void);
 extern void FASTCALL(swap_free(unsigned long));
 struct swap_list_t {
 	int head;	/* head of priority-ordered swapfile list */
@@ -147,7 +147,7 @@
 extern inline unsigned long in_swap_cache(struct page *page)
 {
 	if (PageSwapCache(page))
-		return page->offset;
+		return pgoff2ulong(page->index);
 	return 0;
 }
 
@@ -164,7 +164,7 @@
 		return 1;
 	count = atomic_read(&page->count);
 	if (PageSwapCache(page))
-		count += swap_count(page->offset) - 2;
+		count += swap_count(pgoff2ulong(page->index)) - 2;
 	if (PageFreeAfter(page))
 		count--;
 	return  count > 1;
diff -urN lfs-ref/include/linux/ufs_fs_i.h lfs/include/linux/ufs_fs_i.h
--- lfs-ref/include/linux/ufs_fs_i.h	Tue Feb  1 18:24:19 2000
+++ lfs/include/linux/ufs_fs_i.h	Thu Mar  1 16:41:28 2001
@@ -18,7 +18,6 @@
 		__u32	i_data[15];
 		__u8	i_symlink[4*15];
 	} i_u1;
-	__u64	i_size;
 	__u32	i_flags;
 	__u32	i_gen;
 	__u32	i_shadow;
diff -urN lfs-ref/kernel/ksyms.c lfs/kernel/ksyms.c
--- lfs-ref/kernel/ksyms.c	Thu Mar  1 16:41:12 2001
+++ lfs/kernel/ksyms.c	Thu Mar  1 16:41:28 2001
@@ -95,6 +95,7 @@
 
 /* process memory management */
 EXPORT_SYMBOL(do_mmap);
+EXPORT_SYMBOL(do_mmap_pgoff);
 EXPORT_SYMBOL(do_munmap);
 EXPORT_SYMBOL(exit_mm);
 EXPORT_SYMBOL(exit_files);
diff -urN lfs-ref/lib/vsprintf.c lfs/lib/vsprintf.c
--- lfs-ref/lib/vsprintf.c	Mon Jan 17 16:44:50 2000
+++ lfs/lib/vsprintf.c	Thu Mar  1 16:41:28 2001
@@ -67,10 +67,106 @@
 #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; \
+  __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)
@@ -207,7 +303,10 @@
 		/* get the conversion qualifier */
 		qualifier = -1;
 		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
-			qualifier = *fmt;
+			if (*fmt == 'l' && qualifier == 'l')
+				qualifier = 'L';
+			else
+				qualifier = *fmt;
 			++fmt;
 		}
 
@@ -290,7 +389,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 == 'h') {
 			num = (unsigned short) va_arg(args, int);
diff -urN lfs-ref/mm/filemap.c lfs/mm/filemap.c
--- lfs-ref/mm/filemap.c	Thu Mar  1 16:41:12 2001
+++ lfs/mm/filemap.c	Thu Mar  1 16:41:28 2001
@@ -78,7 +78,7 @@
  * 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 start)
 {
 	struct page ** p;
 	struct page * page;
@@ -86,10 +86,10 @@
 repeat:
 	p = &inode->i_pages;
 	while ((page = *p) != NULL) {
-		unsigned long offset = page->offset;
+		loff_t loffset = pgoff2loff(page->index);
 
 		/* page wholly truncated - free it */
-		if (offset >= start) {
+		if (loffset >= start) {
 			if (PageLocked(page)) {
 				wait_on_page(page);
 				goto repeat;
@@ -105,9 +105,10 @@
 			continue;
 		}
 		p = &page->next;
-		offset = start - offset;
+		loffset = start - loffset;
 		/* partial truncate, clear end of page */
-		if (offset < PAGE_CACHE_SIZE) {
+		if (loffset < PAGE_CACHE_SIZE) {
+			unsigned int  offset  = loffset; /* truncate ok */
 			unsigned long address = page_address(page);
 			memset((void *) (offset + address), 0, PAGE_CACHE_SIZE - offset);
 			flush_page_to_ram(address);
@@ -195,7 +196,8 @@
 		 * were to be marked referenced..
 		 */
 		if (PageSwapCache(page)) {
-			if (referenced && swap_count(page->offset) != 1)
+			if (referenced &&
+			    swap_count(pgoff2ulong(page->index)) != 1)
 				continue;
 			delete_from_swap_cache(page);
 			return 1;
@@ -250,11 +252,12 @@
  * memory maps.  --sct
  */
 
-void update_vm_cache_conditional(struct inode * inode, unsigned long pos, const char * buf, int count, unsigned long source_address)
+void update_vm_cache_conditional(struct inode * inode, loff_t pos, const char * buf, int count, unsigned long source_address)
 {
 	unsigned long offset, len;
+	pgoff_t pgoff = loff2pgoff(pos);
 
-	offset = (pos & ~PAGE_CACHE_MASK);
+	offset = ((unsigned long)pos & ~PAGE_CACHE_MASK);
 	pos = pos & PAGE_CACHE_MASK;
 	len = PAGE_CACHE_SIZE - offset;
 	do {
@@ -262,7 +265,7 @@
 
 		if (len > count)
 			len = count;
-		page = find_page(inode, pos);
+		page = find_page(inode, pgoff);
 		if (page) {
 			char *dest = (char*) (offset + page_address(page));
 
@@ -281,19 +284,20 @@
 	} while (count);
 }
 
-void update_vm_cache(struct inode * inode, unsigned long pos, const char * buf, int count)
+void update_vm_cache(struct inode * inode, loff_t pos, const char * buf, int count)
 {
 	update_vm_cache_conditional(inode, pos, buf, count, 0);
 }
 
 
 static inline void add_to_page_cache(struct page * page,
-	struct inode * inode, unsigned long offset,
-	struct page **hash)
+				     struct inode * inode,
+				     pgoff_t pgoff,
+				     struct page **hash)
 {
 	atomic_inc(&page->count);
 	page->flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced));
-	page->offset = offset;
+	page->index = pgoff;
 	add_page_to_inode_queue(inode, page);
 	__add_page_to_hash_queue(page, hash);
 }
@@ -304,29 +308,32 @@
  * this is all overlapped with the IO on the previous page finishing anyway)
  */
 static unsigned long try_to_read_ahead(struct file * file,
-				unsigned long offset, unsigned long page_cache)
+				       pgoff_t pgoff, unsigned long page_cache)
 {
 	struct inode *inode = file->f_dentry->d_inode;
-	struct page * page;
-	struct page ** hash;
+	pgoff_t pg_size;
 
-	offset &= PAGE_CACHE_MASK;
-	switch (page_cache) {
-	case 0:
+	/* Calculate file size in 'pages' -- if even one byte (according to
+	   the 'i_size') exceeds the final page-size block, round up. */
+	pg_size = loff2pgoff(inode->i_size+(PAGE_SIZE-1));
+
+	if (!page_cache) {
 		page_cache = page_cache_alloc();
 		if (!page_cache)
-			break;
-	default:
-		if (offset >= inode->i_size)
-			break;
-		hash = page_hash(inode, offset);
-		page = __find_page(inode, offset, *hash);
+			return 0; /* Can't allocate! */
+	}
+	/* Ok, we have a page, make sure it is in the page cache */
+	if (pgoff2ulong(pgoff) < pgoff2ulong(pg_size)) {
+		struct page * page;
+		struct page ** hash;
+		hash = page_hash(inode, pgoff);
+		page = __find_page(inode, pgoff, *hash);
 		if (!page) {
 			/*
 			 * Ok, add the new page to the hash-queues...
 			 */
 			page = page_cache_entry(page_cache);
-			add_to_page_cache(page, inode, offset, hash);
+			add_to_page_cache(page, inode, pgoff, hash);
 			inode->i_op->readpage(file, page);
 			page_cache = 0;
 		}
@@ -380,11 +387,11 @@
 
 #define PROFILE_MAXREADCOUNT 1000
 
-static unsigned long total_reada;
-static unsigned long total_async;
-static unsigned long total_ramax;
-static unsigned long total_ralen;
-static unsigned long total_rawin;
+static u_long total_reada;
+static u_long total_async;
+static u_long total_ramax;
+static u_long total_ralen;
+static u_long total_rawin;
 
 static void profile_readahead(int async, struct file *filp)
 {
@@ -492,13 +499,13 @@
 
 static inline unsigned long generic_file_readahead(int reada_ok,
 	struct file * filp, struct inode * inode,
-	unsigned long ppos, struct page * page, unsigned long page_cache)
+	loff_t ppos, struct page * page, unsigned long page_cache)
 {
-	unsigned long max_ahead, ahead;
-	unsigned long raend;
+	loff_t max_ahead, ahead;
+	loff_t raend;
 	int max_readahead = get_max_readahead(inode);
 
-	raend = filp->f_raend & PAGE_CACHE_MASK;
+	raend = filp->f_raend & PAGE_CACHE_MASK_loff;
 	max_ahead = 0;
 
 /*
@@ -556,7 +563,7 @@
 	ahead = 0;
 	while (ahead < max_ahead) {
 		ahead += PAGE_CACHE_SIZE;
-		page_cache = try_to_read_ahead(filp, raend + ahead,
+		page_cache = try_to_read_ahead(filp, loff2pgoff(raend + ahead),
 						page_cache);
 	}
 /*
@@ -625,14 +632,14 @@
 	struct dentry *dentry = filp->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	unsigned long page_cache;
-	size_t pos, pgpos;
+	loff_t pos, posp;
 	int reada_ok;
 	int max_readahead = get_max_readahead(inode);
 
 	page_cache = 0;
 
 	pos = *ppos;
-	pgpos = pos & PAGE_CACHE_MASK;
+	posp = pos & PAGE_CACHE_MASK_loff;
 /*
  * If the current position is outside the previous read-ahead window, 
  * we reset the current read-ahead context and set read ahead max to zero
@@ -640,7 +647,7 @@
  * otherwise, we assume that the file accesses are sequential enough to
  * continue read-ahead.
  */
-	if (pgpos > filp->f_raend || pgpos + filp->f_rawin < filp->f_raend) {
+	if (posp > filp->f_raend || posp + filp->f_rawin < filp->f_raend) {
 		reada_ok = 0;
 		filp->f_raend = 0;
 		filp->f_ralen = 0;
@@ -656,12 +663,12 @@
  * Then, at least MIN_READAHEAD if read ahead is ok,
  * and at most MAX_READAHEAD in all cases.
  */
-	if (pos + desc->count <= (PAGE_CACHE_SIZE >> 1)) {
+	if (pos + desc->count <= (loff_t)(PAGE_CACHE_SIZE >> 1)) {
 		filp->f_ramax = 0;
 	} else {
-		unsigned long needed;
+		loff_t needed;
 
-		needed = ((pos + desc->count) & PAGE_CACHE_MASK) - pgpos;
+		needed = ((pos + desc->count) & PAGE_CACHE_MASK) - posp;
 
 		if (filp->f_ramax < needed)
 			filp->f_ramax = needed;
@@ -674,6 +681,7 @@
 
 	for (;;) {
 		struct page *page, **hash;
+		pgoff_t pgoff;
 
 		if (pos >= inode->i_size)
 			break;
@@ -681,8 +689,9 @@
 		/*
 		 * Try to find the data in the page cache..
 		 */
-		hash = page_hash(inode, pos & PAGE_CACHE_MASK);
-		page = __find_page(inode, pos & PAGE_CACHE_MASK, *hash);
+		pgoff = loff2pgoff(pos);
+		hash = page_hash(inode, pgoff);
+		page = __find_page(inode, pgoff, *hash);
 		if (!page)
 			goto no_cached_page;
 
@@ -695,7 +704,7 @@
  * the page has been rewritten.
  */
 		if (PageUptodate(page) || PageLocked(page))
-			page_cache = generic_file_readahead(reada_ok, filp, inode, pos & PAGE_CACHE_MASK, page, page_cache);
+			page_cache = generic_file_readahead(reada_ok, filp, inode, pos & PAGE_CACHE_MASK_loff, page, page_cache);
 		else if (reada_ok && filp->f_ramax > MIN_READAHEAD)
 				filp->f_ramax = MIN_READAHEAD;
 
@@ -720,8 +729,8 @@
 			flush_dcache_page(page_address(page));
 
 		offset = pos & ~PAGE_CACHE_MASK;
-		nr = PAGE_CACHE_SIZE - offset;
-		if (nr > inode->i_size - pos)
+		nr = PAGE_CACHE_SIZE - offset; /* small value */
+		if ((loff_t)nr > (inode->i_size - pos))
 			nr = inode->i_size - pos;
 
 		/*
@@ -761,7 +770,7 @@
 		 */
 		page = page_cache_entry(page_cache);
 		page_cache = 0;
-		add_to_page_cache(page, inode, pos & PAGE_CACHE_MASK, hash);
+		add_to_page_cache(page, inode, pgoff, hash);
 
 		/*
 		 * Error handling is tricky. If we get a read error,
@@ -842,10 +851,26 @@
 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;
+
+	if (((ssize_t) count) < 0)
+		return -EINVAL;
 
 	retval = -EFAULT;
 	if (access_ok(VERIFY_WRITE, buf, count)) {
 		retval = 0;
+
+		/* L-F-S spec 2.2.1.25: */
+		if (!(filp->f_flags & O_LARGEFILE) &&
+		    S_ISREG(inode->i_mode) &&
+		    (*ppos < inode->i_size) && count) {
+			if (*ppos >= 0x7fffffff) /* pos@2G forbidden */
+				return -EOVERFLOW;
+			if (*ppos + count > 0x7fffffff)
+				/* Read only until end of allowed region */
+				count = 0x7fffffff - *ppos;
+		}
+
 		if (count) {
 			read_descriptor_t desc;
 
@@ -894,6 +919,9 @@
 	struct file * in_file, * out_file;
 	struct inode * in_inode, * out_inode;
 
+	if (((ssize_t) count) < 0)
+		return -EINVAL;
+
 	lock_kernel();
 
 	/*
@@ -987,20 +1015,25 @@
 	struct file * file = area->vm_file;
 	struct dentry * dentry = file->f_dentry;
 	struct inode * inode = dentry->d_inode;
-	unsigned long offset, reada, i;
+	loff_t offset;
+	pgoff_t pgoff, reada;
+	int i;
 	struct page * page, **hash;
 	unsigned long old_page, new_page;
 
 	new_page = 0;
-	offset = (address & PAGE_MASK) - area->vm_start + area->vm_offset;
+	offset = ((loff_t)((address & PAGE_MASK) - area->vm_start) +
+		  area->vm_offset);
+
 	if (offset >= inode->i_size && (area->vm_flags & VM_SHARED) && area->vm_mm == current->mm)
 		goto no_page;
 
 	/*
 	 * Do we have something in the page cache already?
 	 */
-	hash = page_hash(inode, offset);
-	page = __find_page(inode, offset, *hash);
+	pgoff = loff2pgoff(offset);
+	hash = page_hash(inode, pgoff);
+	page = __find_page(inode, pgoff, *hash);
 	if (!page)
 		goto no_cached_page;
 
@@ -1051,11 +1084,12 @@
 	/*
 	 * Try to read in an entire cluster at once.
 	 */
-	reada   = offset;
-	reada >>= PAGE_CACHE_SHIFT + page_cluster;
-	reada <<= PAGE_CACHE_SHIFT + page_cluster;
+	reada   = loff2pgoff(offset);
+	/* Mask lowest  'page_cluster'  worth of the lowest bits */
+	reada   = ulong2pgoff(pgoff2ulong(reada) & ((~(0UL)) << page_cluster));
 
-	for (i = 1 << page_cluster; i > 0; --i, reada += PAGE_CACHE_SIZE)
+	for (i = 1 << page_cluster; i > 0;
+	     --i, reada = ulong2pgoff(pgoff2ulong(reada)+1))
 		new_page = try_to_read_ahead(file, reada, new_page);
 
 	if (!new_page)
@@ -1069,7 +1103,7 @@
 	 * cache.. The page we just got may be useful if we
 	 * can't share, so don't get rid of it here.
 	 */
-	page = find_page(inode, offset);
+	page = find_page(inode, pgoff);
 	if (page)
 		goto found_page;
 
@@ -1078,7 +1112,7 @@
 	 */
 	page = page_cache_entry(new_page);
 	new_page = 0;
-	add_to_page_cache(page, inode, offset, hash);
+	add_to_page_cache(page, inode, pgoff, hash);
 
 	if (inode->i_op->readpage(file, page) != 0)
 		goto failure;
@@ -1127,10 +1161,10 @@
  * if the disk is full.
  */
 static inline int do_write_page(struct inode * inode, struct file * file,
-	const char * page, unsigned long offset)
+				const char * page, loff_t offset)
 {
 	int retval;
-	unsigned long size;
+	loff_t size;
 	loff_t loff = offset;
 	mm_segment_t old_fs;
 
@@ -1154,7 +1188,7 @@
 }
 
 static int filemap_write_page(struct vm_area_struct * vma,
-			      unsigned long offset,
+			      loff_t offset,
 			      unsigned long page)
 {
 	int result;
@@ -1188,7 +1222,7 @@
  */
 int filemap_swapout(struct vm_area_struct * vma, struct page * page)
 {
-	return filemap_write_page(vma, page->offset, page_address(page));
+	return filemap_write_page(vma, pgoff2loff(page->index), page_address(page));
 }
 
 static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
@@ -1552,7 +1586,7 @@
 {
 	struct dentry	*dentry = file->f_dentry; 
 	struct inode	*inode = dentry->d_inode; 
-	unsigned long	pos = *ppos;
+	loff_t		pos = *ppos;
 	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
 	struct page	*page, **hash;
 	unsigned long	page_cache = 0;
@@ -1568,6 +1602,9 @@
 		return error;
 	}
 
+	if (((ssize_t) count) < 0)
+		return -EINVAL;
+
 	sync    = file->f_flags & O_SYNC;
 	written = 0;
 
@@ -1578,31 +1615,39 @@
 	 * Check whether we've reached the file size limit.
 	 */
 	status = -EFBIG;
-	if (pos >= limit) {
+	if (limit != RLIM_INFINITY && pos >= limit) {
 		send_sig(SIGXFSZ, current, 0);
 		goto out;
 	}
 
+	/* L-F-S */
+	if (!(file->f_flags & O_LARGEFILE) &&
+	    S_ISREG(inode->i_mode) && count) {
+		if (pos >= 0x7fffffff) /* pos@2G forbidden */
+			goto out;
+
+		if (pos + count > 0x7fffffff)
+			count = 0x7fffffff - pos;
+	}
+
 	status  = 0;
 	/*
 	 * Check whether to truncate the write,
 	 * and send the signal if we do.
 	 */
-	if (count > limit - pos) {
-		send_sig(SIGXFSZ, current, 0);
+	if (limit != RLIM_INFINITY && count > limit - pos)
 		count = limit - pos;
-	}
 
 	while (count) {
-		unsigned long bytes, pgpos, offset;
+		unsigned long bytes, offset;
+		pgoff_t pgpos = loff2pgoff(pos);
 		char * dest;
 
 		/*
 		 * Try to find the page in the cache. If it isn't there,
 		 * allocate a free page.
 		 */
-		offset = (pos & ~PAGE_CACHE_MASK);
-		pgpos = pos & PAGE_CACHE_MASK;
+		offset = ((unsigned long)pos & ~PAGE_CACHE_MASK);
 		bytes = PAGE_CACHE_SIZE - offset;
 		if (bytes > count)
 			bytes = count;
@@ -1680,15 +1725,14 @@
  * Note: we don't have to worry about races here, as the caller
  * is holding the inode semaphore.
  */
-unsigned long get_cached_page(struct inode * inode, unsigned long offset,
-				int new)
+unsigned long get_cached_page(struct inode * inode, pgoff_t pgoff, int new)
 {
 	struct page * page;
 	struct page ** hash;
 	unsigned long page_cache = 0;
 
-	hash = page_hash(inode, offset);
-	page = __find_page(inode, offset, *hash);
+	hash = page_hash(inode, pgoff);
+	page = __find_page(inode, pgoff, *hash);
 	if (!page) {
 		if (!new)
 			goto out;
@@ -1697,7 +1741,7 @@
 			goto out;
 		clear_page(page_cache);
 		page = page_cache_entry(page_cache);
-		add_to_page_cache(page, inode, offset, hash);
+		add_to_page_cache(page, inode, pgoff, hash);
 	}
 	if (atomic_read(&page->count) != 2)
 		printk(KERN_ERR "get_cached_page: page count=%d\n",
diff -urN lfs-ref/mm/memory.c lfs/mm/memory.c
--- lfs-ref/mm/memory.c	Thu Mar  1 16:41:12 2001
+++ lfs/mm/memory.c	Thu Mar  1 16:41:28 2001
@@ -862,7 +862,7 @@
 	case 2:
 		if (!PageSwapCache(page_map))
 			break;
-		if (swap_count(page_map->offset) != 1)
+		if (swap_count(pgoff2ulong(page_map->index)) != 1)
 			break;
 		delete_from_swap_cache(page_map);
 		/* FallThrough */
@@ -986,7 +986,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)
 {
 	truncate_inode_pages(inode, offset);
 	if (inode->i_mmap)
diff -urN lfs-ref/mm/mmap.c lfs/mm/mmap.c
--- lfs-ref/mm/mmap.c	Thu Mar  1 16:41:11 2001
+++ lfs/mm/mmap.c	Thu Mar  1 16:41:28 2001
@@ -169,11 +169,25 @@
 #undef _trans
 }
 
-unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags, unsigned long off)
+unsigned long do_mmap(struct file *file, unsigned long addr,
+		      unsigned long len, unsigned long prot,
+		      unsigned long flag, unsigned long offset)
+{
+	unsigned long ret = -EINVAL;
+	if ((offset + PAGE_ALIGN(len)) < offset)
+		goto out;
+	if (!(offset & ~PAGE_MASK))
+		ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+out:
+	return ret;
+}
+
+unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long pg_off)
 {
 	struct mm_struct * mm = current->mm;
 	struct vm_area_struct * vma;
+	loff_t off = (loff_t)pg_off << PAGE_SHIFT;
 	int error;
 
 	if (file && (!file->f_op || !file->f_op->mmap))
@@ -847,7 +861,8 @@
 		 * the offsets must be contiguous..
 		 */
 		if ((mpnt->vm_file != NULL) || (mpnt->vm_flags & VM_SHM)) {
-			unsigned long off = prev->vm_offset+prev->vm_end-prev->vm_start;
+			loff_t off = (prev->vm_offset +
+				      (loff_t)(prev->vm_end - prev->vm_start));
 			if (off != mpnt->vm_offset)
 				continue;
 		}
diff -urN lfs-ref/mm/page_alloc.c lfs/mm/page_alloc.c
--- lfs-ref/mm/page_alloc.c	Thu Mar  1 16:41:12 2001
+++ lfs/mm/page_alloc.c	Thu Mar  1 16:41:28 2001
@@ -115,7 +115,7 @@
 	add_mem_queue(area, list(map_nr));
 
 static void free_local_pages(struct page * page) {
-	unsigned long order = page->offset;
+	unsigned long order = page->index;
 	unsigned int type = PageDMA(page) ? 1 : 0;
 	struct free_area_struct *area;
 	unsigned long map_nr = page - mem_map;
@@ -172,7 +172,7 @@
 
 	page = mem_map + map_nr;
 	list_add((struct list_head *) page, &current->local_pages);
-	page->offset = order;
+	page->index = order;
 	current->nr_local_pages++;
 }
 
diff -urN lfs-ref/mm/page_io.c lfs/mm/page_io.c
--- lfs-ref/mm/page_io.c	Tue Jun 13 03:48:15 2000
+++ lfs/mm/page_io.c	Thu Mar  1 16:41:28 2001
@@ -112,7 +112,7 @@
 		 * as if it were: we are not allowed to manipulate the inode
 		 * hashing for locked pages.
 		 */
-		if (page->offset != entry) {
+		if (pgoff2ulong(page->index) != entry) {
 			printk ("swap entry mismatch");
 			return;
 		}
@@ -265,8 +265,8 @@
 		printk("VM: swap page is not in swap cache\n");
 		return;
 	}
-	if (page->offset != entry) {
-		printk ("swap entry mismatch");
+	if (pgoff2ulong(page->index) != entry) {
+		printk ("VM: swap entry mismatch");
 		return;
 	}
 	rw_swap_page_base(rw, entry, page, wait);
@@ -291,12 +291,12 @@
 		printk ("VM: read_swap_page: page already in page cache!\n");
 		return;
 	}
-	page->inode = &swapper_inode;
-	page->offset = entry;
+	page->inode     = &swapper_inode;
+	page->index = ulong2pgoff(entry);
 	atomic_inc(&page->count);	/* Protect from shrink_mmap() */
 	rw_swap_page(rw, entry, buffer, 1);
 	atomic_dec(&page->count);
-	page->inode = 0;
+	page->inode     = 0;
 	clear_bit(PG_swap_cache, &page->flags);
 }
 
diff -urN lfs-ref/mm/swap_state.c lfs/mm/swap_state.c
--- lfs-ref/mm/swap_state.c	Thu Mar  1 16:38:56 2001
+++ lfs/mm/swap_state.c	Thu Mar  1 16:41:28 2001
@@ -54,7 +54,7 @@
 	if (PageTestandSetSwapCache(page)) {
 		printk(KERN_ERR "swap_cache: replacing non-empty entry %08lx "
 		       "on page %08lx\n",
-		       page->offset, page_address(page));
+		       pgoff2ulong(page->index), page_address(page));
 		return 0;
 	}
 	if (page->inode) {
@@ -65,8 +65,8 @@
 	atomic_inc(&page->count);
 	page->flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced));
 	page->inode = &swapper_inode;
-	page->offset = entry;
-	add_page_to_hash_queue(page, &swapper_inode, entry);
+	page->index = ulong2pgoff(entry);
+	add_page_to_hash_queue(page, &swapper_inode, ulong2pgoff(entry));
 	add_page_to_inode_queue(&swapper_inode, page);
 	return 1;
 }
@@ -204,7 +204,7 @@
  */
 void delete_from_swap_cache(struct page *page)
 {
-	long entry = page->offset;
+	long entry = pgoff2ulong(page->index);
 
 #ifdef SWAP_CACHE_INFO
 	swap_cache_del_total++;
@@ -252,7 +252,7 @@
 	swap_cache_find_total++;
 #endif
 	while (1) {
-		found = find_page(&swapper_inode, entry);
+		found = find_page(&swapper_inode, ulong2pgoff(entry));
 		if (!found)
 			return 0;
 		if (found->inode != &swapper_inode || !PageSwapCache(found))
diff -urN lfs-ref/mm/vmscan.c lfs/mm/vmscan.c
--- lfs-ref/mm/vmscan.c	Thu Mar  1 16:41:12 2001
+++ lfs/mm/vmscan.c	Thu Mar  1 16:41:28 2001
@@ -74,7 +74,7 @@
 	 * memory, and we should just continue our scan.
 	 */
 	if (PageSwapCache(page_map)) {
-		entry = page_map->offset;
+		entry = pgoff2ulong(page_map->index);
 		swap_duplicate(entry);
 		set_pte(page_table, __pte(entry));
 drop_pte:
--- linux/drivers/block/loop.c.orig	Tue Mar 27 17:22:53 2001
+++ linux/drivers/block/loop.c	Tue Mar 27 17:23:51 2001
@@ -153,10 +153,10 @@
 				 struct dentry * lo_dentry, kdev_t lodev)
 {
 	if (S_ISREG(lo_dentry->d_inode->i_mode))
-		return (lo_dentry->d_inode->i_size - lo->lo_offset) / BLOCK_SIZE;
+		return (lo_dentry->d_inode->i_size - lo->lo_offset) >> BLOCK_SIZE_BITS;
 	if (blk_size[MAJOR(lodev)])
 		return blk_size[MAJOR(lodev)][MINOR(lodev)] -
-			lo->lo_offset / BLOCK_SIZE;
+			(lo->lo_offset >> BLOCK_SIZE_BITS);
 	return MAX_DISK_SIZE;
 }
 
--- linux/drivers/isdn/avmb1/capifs.c.org	Wed Mar 28 10:43:15 2001
+++ linux/drivers/isdn/avmb1/capifs.c	Wed Mar 28 10:43:56 2001
@@ -167,12 +167,12 @@
 	switch(nr)
 	{
 	case 0:
-		if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
+		if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
 	case 1:
-		if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
+		if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
@@ -184,7 +184,7 @@
 				char *p = numbuf;
 				if (np->type) *p++ = np->type;
 				sprintf(p, "%u", np->num);
-				if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr) < 0 )
+				if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_UNKNOWN) < 0 )
 					return 0;
 			}
 			filp->f_pos = ++nr;

--Boundary_(ID_AscQuEPNMMSXRYrZaPpRTg)
Content-id: <Pine.SOL.4.33.0109130900041.24390@tersk10.SLAC.Stanford.EDU>
Content-type: TEXT/PLAIN; charset=US-ASCII; name=linux-2.2.16-lfs-headers.patch
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=linux-2.2.16-lfs-headers.patch
Content-description: linux-2.2.16-lfs-headers.patch

--- linux/include/asm-i386/fcntl.h.jj	Wed Oct 21 19:02:48 1998
+++ linux/include/asm-i386/fcntl.h	Wed Jan  5 09:20:13 2000
@@ -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 @@ struct flock {
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
 };
 
 #endif
--- linux/include/asm-i386/unistd.h.jj	Wed Jan 20 20:06:24 1999
+++ linux/include/asm-i386/unistd.h	Wed Jan  5 12:19:27 2000
@@ -80,7 +80,7 @@
 #define __NR_sigpending		 73
 #define __NR_sethostname	 74
 #define __NR_setrlimit		 75
-#define __NR_getrlimit		 76
+#define __NR_getrlimit		 76	/* Back compatible 2Gig limited rlimit */
 #define __NR_getrusage		 77
 #define __NR_gettimeofday	 78
 #define __NR_settimeofday	 79
@@ -195,8 +195,15 @@
 #define __NR_getpmsg		188	/* some people actually want streams */
 #define __NR_putpmsg		189	/* some people actually want streams */
 #define __NR_vfork		190
+/* #define __NR_ugetrlimit		191	SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
 
-/* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
+/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
 #define __syscall_return(type, res) \
 do { \
@@ -269,6 +276,19 @@ __asm__ volatile ("int $0x80" \
 	: "=a" (__res) \
 	: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
 	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+long __res; \
+__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
+	: "=a" (__res) \
+	: "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
+	  "0" ((long)(arg6))); \
 __syscall_return(type,__res); \
 }
 
--- linux/include/asm-mips/fcntl.h.jj	Mon Aug  9 21:04:41 1999
+++ linux/include/asm-mips/fcntl.h	Wed Jan  5 09:20:13 2000
@@ -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,13 @@ typedef struct flock {
 	__kernel_pid_t l_pid;
 	long  pad[4];			/* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
 } flock_t;
+
+typedef struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
+} flock64_t;
 
 #endif /* __ASM_MIPS_FCNTL_H */
--- linux/include/asm-alpha/fcntl.h.jj	Wed Oct 21 19:02:48 1998
+++ linux/include/asm-alpha/fcntl.h	Wed Jan  5 09:25:15 2000
@@ -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 /* will be set by the kernel on every open */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -61,5 +62,9 @@ struct flock {
 	__kernel_off_t l_len;
 	__kernel_pid_t l_pid;
 };
+
+#ifdef __KERNEL__
+#define flock64	flock
+#endif
 
 #endif
--- linux/include/asm-m68k/fcntl.h.jj	Wed Oct 21 22:30:56 1998
+++ linux/include/asm-m68k/fcntl.h	Wed Jan  5 09:20:13 2000
@@ -33,6 +33,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 +62,14 @@ struct flock {
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
 };
 
 #endif /* _M68K_FCNTL_H */
--- linux/include/asm-m68k/stat.h.jj	Mon Oct  5 21:33:40 1998
+++ linux/include/asm-m68k/stat.h	Wed Jan  5 09:20:13 2000
@@ -38,4 +38,8 @@ struct stat {
 	unsigned long  __unused5;
 };
 
+/* stat64 struct goes here -- someone please make
+ * it mesh with whatever glibc does in userland on
+ * m68k's.
+ */
 #endif /* _M68K_STAT_H */
--- linux/include/asm-m68k/unistd.h.jj	Tue Jan 19 19:58:34 1999
+++ linux/include/asm-m68k/unistd.h	Wed Jan  5 12:20:31 2000
@@ -80,7 +80,7 @@
 #define __NR_sigpending		 73
 #define __NR_sethostname	 74
 #define __NR_setrlimit		 75
-#define __NR_getrlimit		 76
+#define __NR_getrlimit	 	 76
 #define __NR_getrusage		 77
 #define __NR_gettimeofday	 78
 #define __NR_settimeofday	 79
@@ -194,6 +194,13 @@
 #define __NR_getpmsg		188	/* some people actually want streams */
 #define __NR_putpmsg		189	/* some people actually want streams */
 #define __NR_vfork		190
+/* #define __NR_getrlimit		191 */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
--- linux/include/asm-sparc/fcntl.h.jj	Tue Oct 27 18:52:21 1998
+++ linux/include/asm-sparc/fcntl.h	Wed Jan  5 09:20:13 2000
@@ -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	/* LFS */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -32,6 +33,9 @@
 #define F_SETLKW	9
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
+#define F_GETLK64	12
+#define F_SETLK64	13
+#define F_SETLKW64	14
 
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
@@ -57,6 +61,15 @@ struct flock {
 	short l_whence;
 	off_t l_start;
 	off_t l_len;
+	pid_t l_pid;
+	short __unused;
+};
+
+struct flock64 {
+	short l_type;
+	short l_whence;
+	loff_t l_start;
+	loff_t l_len;
 	pid_t l_pid;
 	short __unused;
 };
--- linux/include/asm-sparc/stat.h.jj	Wed Aug  5 01:03:35 1998
+++ linux/include/asm-sparc/stat.h	Tue Dec 21 15:04:32 1999
@@ -1,4 +1,4 @@
-/* $Id: stat.h,v 1.9 1998/07/26 05:24:39 davem Exp $ */
+/* $Id: stat.h,v 1.10 1999/12/21 14:09:41 jj Exp $ */
 #ifndef _SPARC_STAT_H
 #define _SPARC_STAT_H
 
@@ -36,6 +36,42 @@ struct stat {
 	off_t   st_blksize;
 	off_t   st_blocks;
 	unsigned long  __unused4[2];
+};
+
+struct stat64 {
+	unsigned char	__pad0[6];
+	unsigned short	st_dev;
+	unsigned char	__pad1[4];
+
+	unsigned int	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+
+	unsigned char	__pad2[6];
+	unsigned short	st_rdev;
+
+	unsigned char	__pad3[8];
+
+	long long	st_size;
+	unsigned int	st_blksize;
+
+	unsigned char	__pad4[8];
+	unsigned int	st_blocks;
+
+	unsigned int	st_atime;
+	unsigned int	__unused1;
+
+	unsigned int	st_mtime;
+	unsigned int	__unused2;
+
+	unsigned int	st_ctime;
+	unsigned int	__unused3;
+
+	unsigned int	__unused4;
+	unsigned int	__unused5;
 };
 
 #endif
--- linux/include/asm-sparc/unistd.h.jj	Fri Apr 23 04:24:52 1999
+++ linux/include/asm-sparc/unistd.h	Wed Jan  5 09:32:26 2000
@@ -71,14 +71,14 @@
 /* #define __NR_mctl             53    SunOS specific                              */
 #define __NR_ioctl               54 /* Common                                      */
 #define __NR_reboot              55 /* Common                                      */
-/* #define __NR_ni_syscall       56    ENOSYS under SunOS                          */
+#define __NR_mmap2		 56 /* Linux sparc32 Specific			   */
 #define __NR_symlink             57 /* Common                                      */
 #define __NR_readlink            58 /* Common                                      */
 #define __NR_execve              59 /* Common                                      */
 #define __NR_umask               60 /* Common                                      */
 #define __NR_chroot              61 /* Common                                      */
 #define __NR_fstat               62 /* Common                                      */
-/* #define __NR_ni_syscall       63    ENOSYS under SunOS                          */
+#define __NR_fstat64		 63 /* Linux sparc32 Specific			   */
 #define __NR_getpagesize         64 /* Common                                      */
 #define __NR_msync               65 /* Common in newer 1.3.x revs...               */
 #define __NR_vfork               66 /* Common                                      */
@@ -92,14 +92,14 @@
 #define __NR_mprotect            74 /* Common                                      */
 /* #define __NR_madvise          75    SunOS Specific                              */
 #define __NR_vhangup             76 /* Common                                      */
-/* #define __NR_ni_syscall       77    ENOSYS under SunOS                          */
+#define __NR_truncate64		 77 /* Linux sparc32 Specific			   */
 /* #define __NR_mincore          78    SunOS Specific                              */
 #define __NR_getgroups           79 /* Common                                      */
 #define __NR_setgroups           80 /* Common                                      */
 #define __NR_getpgrp             81 /* Common                                      */
 /* #define __NR_setpgrp          82    setpgid, same difference...                 */
 #define __NR_setitimer           83 /* Common                                      */
-/* #define __NR_ni_syscall       84    ENOSYS under SunOS                          */
+#define __NR_ftruncate64	 84 /* Linux sparc32 Specific			   */
 #define __NR_swapon              85 /* Common                                      */
 #define __NR_getitimer           86 /* Common                                      */
 /* #define __NR_gethostname      87    SunOS Specific                              */
@@ -147,14 +147,14 @@
 #define __NR_truncate           129 /* Common                                      */
 #define __NR_ftruncate          130 /* Common                                      */
 #define __NR_flock              131 /* Common                                      */
-/* #define __NR_ni_syscall      132    ENOSYS under SunOS                          */
+#define __NR_lstat64		132 /* Linux sparc32 Specific			   */
 #define __NR_sendto             133 /* Common                                      */
 #define __NR_shutdown           134 /* Common                                      */
 #define __NR_socketpair         135 /* Common                                      */
 #define __NR_mkdir              136 /* Common                                      */
 #define __NR_rmdir              137 /* Common                                      */
 #define __NR_utimes             138 /* SunOS Specific                              */
-/* #define __NR_ni_syscall      139    ENOSYS under SunOS                          */
+#define __NR_stat64		139 /* Linux sparc32 Specific			   */
 /* #define __NR_adjtime         140    SunOS Specific                              */
 #define __NR_getpeername        141 /* Common                                      */
 /* #define __NR_gethostid       142    SunOS Specific                              */
--- linux/include/asm-ppc/fcntl.h.jj	Wed Oct 21 22:31:06 1998
+++ linux/include/asm-ppc/fcntl.h	Wed Jan  5 09:28:42 2000
@@ -18,6 +18,8 @@
 #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
+#define O_DIRECT	0400000	/* direct disk access hint - currently ignored */
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -33,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 */
 
@@ -64,6 +70,14 @@ struct flock {
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
 };
 
 #endif
--- linux/include/asm-sparc64/fcntl.h.jj	Tue Oct 27 18:52:21 1998
+++ linux/include/asm-sparc64/fcntl.h	Wed Jan  5 11:27:28 2000
@@ -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
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -32,6 +33,11 @@
 #define F_SETLKW	9
 #define F_SETSIG	10	/*  for sockets. */
 #define F_GETSIG	11	/*  for sockets. */
+#ifdef __KERNEL__
+#define F_GETLK64	12
+#define F_SETLK64	13
+#define F_SETLKW64	14
+#endif
 
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
@@ -58,7 +64,6 @@ struct flock {
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
-	short __unused;
 };
 
 #ifdef __KERNEL__
@@ -70,6 +75,17 @@ struct flock32 {
 	__kernel_pid_t32 l_pid;
 	short __unused;
 };
+
+struct flock32_64 {
+	short l_type;
+	short l_whence;
+	__kernel_loff_t32 l_start;
+	__kernel_loff_t32 l_len;
+	__kernel_pid_t32 l_pid;
+	short __unused;
+};
+
+#define flock64 flock
 #endif
 
 #endif /* !(_SPARC64_FCNTL_H) */
--- linux/include/asm-sparc64/stat.h.jj	Wed Aug  5 01:03:35 1998
+++ linux/include/asm-sparc64/stat.h	Wed Jan  5 12:37:06 2000
@@ -1,4 +1,4 @@
-/* $Id: stat.h,v 1.5 1998/07/26 05:24:41 davem Exp $ */
+/* $Id: stat.h,v 1.6 1999/12/21 14:09:48 jj Exp $ */
 #ifndef _SPARC64_STAT_H
 #define _SPARC64_STAT_H
 
@@ -41,5 +41,46 @@ struct stat {
 	off_t   st_blocks;
 	unsigned long  __unused4[2];
 };
+
+#ifdef __KERNEL__
+/* This is sparc32 stat64 structure. */
+
+struct stat64 {
+	unsigned char	__pad0[6];
+	unsigned short	st_dev;
+	unsigned char	__pad1[4];
+
+	unsigned int	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+
+	unsigned char	__pad2[6];
+	unsigned short	st_rdev;
+
+	unsigned char	__pad3[8];
+
+	long long	st_size;
+	unsigned int	st_blksize;
+
+	unsigned char	__pad4[8];
+	unsigned int	st_blocks;
+
+	unsigned int	st_atime;
+	unsigned int	__unused1;
+
+	unsigned int	st_mtime;
+	unsigned int	__unused2;
+
+	unsigned int	st_ctime;
+	unsigned int	__unused3;
+
+	unsigned int	__unused4;
+	unsigned int	__unused5;
+};
+
+#endif
 
 #endif
--- linux/include/asm-sparc64/unistd.h.jj	Fri Apr 23 04:24:52 1999
+++ linux/include/asm-sparc64/unistd.h	Wed Jan  5 09:35:43 2000
@@ -71,14 +71,14 @@
 /* #define __NR_mctl             53    SunOS specific                              */
 #define __NR_ioctl               54 /* Common                                      */
 #define __NR_reboot              55 /* Common                                      */
-/* #define __NR_ni_syscall       56    ENOSYS under SunOS                          */
+/* #define __NR_mmap2		 56    Linux sparc32 Specific                      */
 #define __NR_symlink             57 /* Common                                      */
 #define __NR_readlink            58 /* Common                                      */
 #define __NR_execve              59 /* Common                                      */
 #define __NR_umask               60 /* Common                                      */
 #define __NR_chroot              61 /* Common                                      */
 #define __NR_fstat               62 /* Common                                      */
-/* #define __NR_ni_syscall       63    ENOSYS under SunOS                          */
+/* #define __NR_fstat64          63    Linux sparc32 Specific                      */
 #define __NR_getpagesize         64 /* Common                                      */
 #define __NR_msync               65 /* Common in newer 1.3.x revs...               */
 #define __NR_vfork               66 /* Common                                      */
@@ -92,14 +92,14 @@
 #define __NR_mprotect            74 /* Common                                      */
 /* #define __NR_madvise          75    SunOS Specific                              */
 #define __NR_vhangup             76 /* Common                                      */
-/* #define __NR_ni_syscall       77    ENOSYS under SunOS                          */
+/* #define __NR_truncate64       77    Linux sparc32 Specific			   */
 /* #define __NR_mincore          78    SunOS Specific                              */
 #define __NR_getgroups           79 /* Common                                      */
 #define __NR_setgroups           80 /* Common                                      */
 #define __NR_getpgrp             81 /* Common                                      */
 /* #define __NR_setpgrp          82    setpgid, same difference...                 */
 #define __NR_setitimer           83 /* Common                                      */
-/* #define __NR_ni_syscall       84    ENOSYS under SunOS                          */
+/* #define __NR_ftruncate64      84    Linux sparc32 Specific			   */
 #define __NR_swapon              85 /* Common                                      */
 #define __NR_getitimer           86 /* Common                                      */
 /* #define __NR_gethostname      87    SunOS Specific                              */
@@ -147,19 +147,19 @@
 #define __NR_truncate           129 /* Common                                      */
 #define __NR_ftruncate          130 /* Common                                      */
 #define __NR_flock              131 /* Common                                      */
-/* #define __NR_ni_syscall      132    ENOSYS under SunOS                          */
+/* #define __NR_lstat64		132    Linux sparc32 Specific                      */
 #define __NR_sendto             133 /* Common                                      */
 #define __NR_shutdown           134 /* Common                                      */
 #define __NR_socketpair         135 /* Common                                      */
 #define __NR_mkdir              136 /* Common                                      */
 #define __NR_rmdir              137 /* Common                                      */
 #define __NR_utimes             138 /* SunOS Specific                              */
-/* #define __NR_ni_syscall      139    ENOSYS under SunOS                          */
+/* #define __NR_stat64		139    Linux sparc32 Specific			   */
 /* #define __NR_adjtime         140    SunOS Specific                              */
 #define __NR_getpeername        141 /* Common                                      */
 /* #define __NR_gethostid       142    SunOS Specific                              */
 /* #define __NR_ni_syscall      143    ENOSYS under SunOS                          */
-#define __NR_getrlimit          144 /* Common                                      */
+#define __NR_getrlimit		144 /* Common                                      */
 #define __NR_setrlimit          145 /* Common                                      */
 /* #define __NR_killpg          146    SunOS Specific                              */
 #define __NR_prctl		147 /* ENOSYS under SunOS                          */
--- linux/include/asm-arm/fcntl.h.jj	Wed Oct 21 22:30:46 1998
+++ linux/include/asm-arm/fcntl.h	Wed Jan  5 09:30:20 2000
@@ -18,6 +18,8 @@
 #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_DIRECT	0200000 /* direct disk access hint - currently ignored */
+#define O_LARGEFILE	0400000
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get f_flags */
@@ -33,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 */
 
@@ -58,6 +64,14 @@ struct flock {
 	off_t l_start;
 	off_t l_len;
 	pid_t l_pid;
+};
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	loff_t l_start;
+	loff_t l_len;
+	pid_t  l_pid;
 };
 
 #endif
--- linux/include/asm-arm/stat.h.jj	Wed Aug  5 01:07:17 1998
+++ linux/include/asm-arm/stat.h	Wed Jan  5 09:20:13 2000
@@ -38,4 +38,5 @@ struct stat {
 	unsigned long  __unused5;
 };
 
+/* Someone please add a glibc/arm compatible stat64 struct here. */
 #endif
--- linux/include/asm-arm/unistd.h.jj	Sat May  8 20:06:58 1999
+++ linux/include/asm-arm/unistd.h	Wed Jan  5 12:21:17 2000
@@ -198,6 +198,13 @@
 					/* 188 reserved */
 					/* 189 reserved */
 #define __NR_vfork			(__NR_SYSCALL_BASE+190)
+/* #define __NR_getrlimit			(__NR_SYSCALL_BASE+191) */
+#define __NR_mmap2			(__NR_SYSCALL_BASE+192)
+#define __NR_truncate64			(__NR_SYSCALL_BASE+193)
+#define __NR_ftruncate64		(__NR_SYSCALL_BASE+194)
+#define __NR_stat64			(__NR_SYSCALL_BASE+195)
+#define __NR_lstat64			(__NR_SYSCALL_BASE+196)
+#define __NR_fstat64			(__NR_SYSCALL_BASE+197)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)

--Boundary_(ID_AscQuEPNMMSXRYrZaPpRTg)--