	These are selected bits out of the 
		lfs-patches-v0.21-base-2.3.27-pre1.diff.A
	file

	This file contains pathconf mechanisms
	( + inseparable  *stat64() at fs/stat.c )
	( + sys_sysconf() syscall )

diff -ur linux-23027p1/fs/adfs/dir.c linux-23027p1m1/fs/adfs/dir.c
--- linux-23027p1/fs/adfs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/adfs/dir.c	Mon Nov  8 22:58:50 1999
@@ -9,6 +9,7 @@
 #include <linux/adfs_fs.h>
 #include <linux/sched.h>
 #include <linux/stat.h>
+#include <linux/unistd.h>
 
 static ssize_t adfs_dirread (struct file *filp, char *buf,
 			     size_t siz, loff_t *ppos)
@@ -17,6 +18,7 @@
 }
 
 static int adfs_readdir (struct file *, void *, filldir_t);
+extern long adfs_pathconf(struct inode *, long);
 
 static struct file_operations adfs_dir_operations = {
 	NULL,			/* lseek - default */
@@ -32,7 +34,7 @@
 	file_fsync,		/* fsync */
 	NULL,			/* fasync */
 	NULL,			/* check_media_change */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
 };
 
 /*
@@ -346,4 +348,30 @@
 	}
 	adfs_dir_free (bh, buffers);
 	return 0;
+}
+
+long adfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return ADFS_NAME_LEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 2;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/adfs/file.c linux-23027p1m1/fs/adfs/file.c
--- linux-23027p1/fs/adfs/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/adfs/file.c	Mon Nov  8 22:58:50 1999
@@ -48,6 +48,8 @@
 	NULL			/* revalidate		*/
 };
 
+extern long adfs_pathconf(struct inode *, long);
+
 struct inode_operations adfs_file_inode_operations = {
 	&adfs_file_operations,	/* default file operations	*/
 	NULL,			/* create			*/
@@ -68,5 +70,6 @@
 	NULL,			/* truncate			*/
 	NULL,			/* permission			*/
 	NULL,			/* smap				*/
-	NULL			/* revalidate			*/
+	NULL,			/* revalidate			*/
+	adfs_pathconf,		/* pathconf			*/
 };
diff -ur linux-23027p1/fs/affs/dir.c linux-23027p1m1/fs/affs/dir.c
--- linux-23027p1/fs/affs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/affs/dir.c	Mon Nov  8 22:58:51 1999
@@ -23,9 +23,11 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/amigaffs.h>
+#include <linux/unistd.h>
 
 static int affs_readdir(struct file *, void *, filldir_t);
 static ssize_t affs_dir_read(struct file *, char *, size_t, loff_t *);
+extern long affs_pathconf(struct inode *inode, long option);
 
 static struct file_operations affs_dir_operations = {
 	NULL,			/* lseek - default */
@@ -64,7 +66,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permissions */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	affs_pathconf,		/* pathconf */
 };
 
 static ssize_t
@@ -181,4 +184,30 @@
 	affs_brelse(fh_bh);
 	pr_debug("AFFS: readdir()=%d\n",stored);
 	return stored;
+}
+
+long affs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return 30;	/* name component max length */
+	case _PC_NO_TRUNC:
+		return 0;	/* Will *silently* truncate */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return -INT_MAX; /* Unknown ?? */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/bad_inode.c linux-23027p1m1/fs/bad_inode.c
--- linux-23027p1/fs/bad_inode.c	Sat Jun 26 22:04:39 1999
+++ linux-23027p1m1/fs/bad_inode.c	Mon Nov  8 22:58:51 1999
@@ -67,7 +67,8 @@
 	EIO_ERROR,		/* truncate */
 	EIO_ERROR,		/* permission */
 	EIO_ERROR,		/* smap */
-	EIO_ERROR		/* revalidate */
+	EIO_ERROR,		/* revalidate */
+	EIO_ERROR,		/* pathconf */
 };
 
 
diff -ur linux-23027p1/fs/coda/dir.c linux-23027p1m1/fs/coda/dir.c
--- linux-23027p1/fs/coda/dir.c	Mon Aug 23 20:14:44 1999
+++ linux-23027p1m1/fs/coda/dir.c	Mon Nov  8 22:58:51 1999
@@ -18,6 +18,7 @@
 #include <asm/segment.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
+#include <linux/unistd.h>
 
 #include <linux/coda.h>
 #include <linux/coda_linux.h>
@@ -50,7 +51,8 @@
 /* support routines */
 static int coda_venus_readdir(struct file *filp, void *dirent, 
 			      filldir_t filldir);
-int coda_fsync(struct file *, struct dentry *dentry);
+extern int coda_fsync(struct file *, struct dentry *dentry);
+extern long coda_pathconf(struct inode *, long);
 
 int coda_crossvol_rename = 0;
 int coda_hasmknod = 0;
@@ -84,8 +86,8 @@
 	NULL,	                /* truncate */
 	coda_permission,        /* permission */
 	NULL,                   /* smap */
-	NULL,                   /* update page */
-        coda_revalidate_inode   /* revalidate */
+	coda_revalidate_inode,	/* revalidate */
+	coda_pathconf,		/* pathconf */
 };
 
 struct file_operations coda_dir_operations = {
@@ -909,3 +911,29 @@
 	return 0;
 }
 
+long coda_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return CODA_MAXNAMLEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+		return 1;	/* Will yield -ENAMETOOLONG */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32; /* 64-bits really, except local cache isn't
+			      very good (at all) at it... */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return -INT_MAX; /* Unknown ?? */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
diff -ur linux-23027p1/fs/buffer.c linux-23027p1m1/fs/buffer.c
--- linux-23027p1/fs/buffer.c	Fri Nov  5 05:36:33 1999
+++ linux-23027p1m1/fs/buffer.c	Mon Nov  8 22:58:51 1999
@@ -43,6 +43,7 @@
 #include <linux/quotaops.h>
 #include <linux/iobuf.h>
 #include <linux/highmem.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -ur linux-23027p1/fs/coda/file.c linux-23027p1m1/fs/coda/file.c
--- linux-23027p1/fs/coda/file.c	Sat Oct 30 02:45:32 1999
+++ linux-23027p1m1/fs/coda/file.c	Mon Nov  8 22:58:51 1999
@@ -32,7 +32,8 @@
 static int coda_file_mmap(struct file * file, struct vm_area_struct * vma);
 
 /* also exported from this file (used for dirs) */
-int coda_fsync(struct file *, struct dentry *dentry);
+extern int coda_fsync(struct file *, struct dentry *dentry);
+extern long coda_pathconf(struct inode *, long);
 
 struct inode_operations coda_file_inode_operations = {
 	&coda_file_operations,	/* default file operations */
@@ -54,7 +55,8 @@
 	NULL,			/* truncate */
         coda_permission,        /* permission */
 	NULL,                   /* smap */
-        coda_revalidate_inode   /* revalidate */
+	coda_revalidate_inode,	/* revalidate */
+	coda_pathconf,		/* pathconf */
 };
 
 struct file_operations coda_file_operations = {
@@ -98,7 +100,7 @@
         coda_prepare_openfile(coda_inode, coda_file, cii->c_ovp,
 			      &cont_file, &cont_dentry);
 
-        CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", 
+        CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page index: %lx\n", 
 	       coda_inode->i_ino, cii->c_ovp->i_ino, page->index);
 
         block_read_full_page(&cont_file, page);
diff -ur linux-23027p1/fs/devices.c linux-23027p1m1/fs/devices.c
--- linux-23027p1/fs/devices.c	Sun Jul  4 20:02:30 1999
+++ linux-23027p1m1/fs/devices.c	Mon Nov  8 22:58:51 1999
@@ -285,7 +285,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	NULL,			/* pathconf */
 };
 
 /*
@@ -342,7 +343,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	NULL,			/* pathconf */
 };
 
 /*
diff -ur linux-23027p1/fs/ext2/dir.c linux-23027p1m1/fs/ext2/dir.c
--- linux-23027p1/fs/ext2/dir.c	Thu Oct 28 23:23:10 1999
+++ linux-23027p1m1/fs/ext2/dir.c	Mon Nov  8 22:58:51 1999
@@ -30,6 +30,7 @@
 }
 
 static int ext2_readdir(struct file *, void *, filldir_t);
+extern long ext2_pathconf(struct inode *, long);
 
 static struct file_operations ext2_dir_operations = {
 	NULL,			/* lseek - default */
@@ -71,7 +72,8 @@
 	NULL,			/* truncate */
 	ext2_permission,	/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ext2_pathconf,		/* pathconf */
 };
 
 int ext2_check_dir_entry (const char * function, struct inode * dir,
diff -ur linux-23027p1/fs/ext2/file.c linux-23027p1m1/fs/ext2/file.c
--- linux-23027p1/fs/ext2/file.c	Fri Nov  5 19:57:30 1999
+++ linux-23027p1m1/fs/ext2/file.c	Mon Nov  8 22:58:51 1999
@@ -21,8 +21,9 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/unistd.h>
 
-
+extern long ext2_pathconf(struct inode *, long);
 
 #define	NBUF	32
 
@@ -30,9 +31,6 @@
 #define MAX(a,b) (((a)>(b))?(a):(b))
 
 static long long ext2_file_lseek(struct file *, long long, int);
-#if BITS_PER_LONG < 64
-static int ext2_open_file (struct inode *, struct file *);
-#endif
 
 #define EXT2_MAX_SIZE(bits)							\
 	(((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) + 				\
@@ -45,9 +43,6 @@
 EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
 };
 
-/*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
 static long long ext2_file_lseek(
 	struct file *file,
 	long long offset,
@@ -62,10 +57,19 @@
 		case 1:
 			offset += file->f_pos;
 	}
-	if (((unsigned long long) offset >> 32) != 0) {
+	if (offset < 0)
+		return -EINVAL;
+	if ((offset >> 32) != 0) {
 		if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
 			return -EINVAL;
 	} 
+
+	/* L-F-S spec 2.2.1.27: */
+	if (!(file->f_flags & O_LARGEFILE)) {
+		if (!off_t_presentable(offset +1)) /* pos@LONG_MAX forbidden */
+			return -EOVERFLOW;
+	}
+
 	if (offset != file->f_pos) {
 		file->f_pos = offset;
 		file->f_reada = 0;
@@ -120,20 +124,6 @@
 	return 0;
 }
 
-#if BITS_PER_LONG < 64
-/*
- * Called when an inode is about to be open.
- * We use this to disallow opening RW large files on 32bit systems if
- * the caller didn't specify O_LARGEFILE.
- */
-static int ext2_open_file (struct inode * inode, struct file * filp)
-{
-	if (inode->u.ext2_i.i_high_size && !(filp->f_flags & O_LARGEFILE))
-		return -EFBIG;
-	return 0;
-}
-#endif
-
 /*
  * We have mostly NULL's here: the current defaults are ok for
  * the ext2 filesystem.
@@ -146,11 +136,7 @@
 	NULL,			/* poll - default */
 	ext2_ioctl,		/* ioctl */
 	generic_file_mmap,	/* mmap */
-#if BITS_PER_LONG == 64	
 	NULL,			/* no special open is needed */
-#else
-	ext2_open_file,
-#endif
 	NULL,			/* flush */
 	ext2_release_file,	/* release */
 	ext2_sync_file,		/* fsync */
@@ -180,4 +166,31 @@
 	ext2_permission,	/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	ext2_pathconf,		/* pathconf */
 };
+
+long ext2_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return EXT2_NAME_LEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 64; /* FIXME: L-F-S:  mount-option: nolargefiles ? */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return EXT2_LINK_MAX;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
diff -ur linux-23027p1/fs/fat/file.c linux-23027p1m1/fs/fat/file.c
--- linux-23027p1/fs/fat/file.c	Sat Nov  6 02:27:28 1999
+++ linux-23027p1m1/fs/fat/file.c	Mon Nov  8 22:58:51 1999
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/pagemap.h>
 #include <linux/fat_cvf.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -64,7 +65,8 @@
 	fat_truncate,		/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	fat_statvfs,		/* statvfs */
 };
 
 ssize_t fat_file_read(
@@ -196,4 +198,31 @@
 	MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 	mark_inode_dirty(inode);
+}
+
+long fat_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  // FIXME: Detect VFAT operational mode of SB ! (namemax: 260)
+	  return 8+1+3;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/fifo.c linux-23027p1m1/fs/fifo.c
--- linux-23027p1/fs/fifo.c	Tue Aug 24 20:12:00 1999
+++ linux-23027p1m1/fs/fifo.c	Mon Nov  8 22:58:51 1999
@@ -11,6 +11,7 @@
 
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 static int fifo_open(struct inode *inode, struct file *filp)
 {
@@ -187,7 +188,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	NULL,			/* pathconf */
 };
 
 
diff -ur linux-23027p1/fs/hfs/dir_cap.c linux-23027p1m1/fs/hfs/dir_cap.c
--- linux-23027p1/fs/hfs/dir_cap.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/dir_cap.c	Mon Nov  8 22:58:51 1999
@@ -94,7 +94,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 struct inode_operations hfs_cap_fdir_inode_operations = {
@@ -117,7 +118,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 struct inode_operations hfs_cap_rdir_inode_operations = {
@@ -140,7 +142,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ File-local functions ================*/
diff -ur linux-23027p1/fs/hfs/dir_dbl.c linux-23027p1m1/fs/hfs/dir_dbl.c
--- linux-23027p1/fs/hfs/dir_dbl.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/dir_dbl.c	Mon Nov  8 22:58:51 1999
@@ -93,7 +93,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 
diff -ur linux-23027p1/fs/hfs/dir_nat.c linux-23027p1m1/fs/hfs/dir_nat.c
--- linux-23027p1/fs/hfs/dir_nat.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/dir_nat.c	Mon Nov  8 22:58:51 1999
@@ -100,7 +100,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL                    /* revalidate */
+	NULL,                   /* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 struct inode_operations hfs_nat_hdir_inode_operations = {
@@ -123,7 +124,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL                    /* revalidate */
+	NULL,                   /* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ File-local functions ================*/
diff -ur linux-23027p1/fs/hfs/file.c linux-23027p1m1/fs/hfs/file.c
--- linux-23027p1/fs/hfs/file.c	Sat Nov  6 01:53:26 1999
+++ linux-23027p1m1/fs/hfs/file.c	Mon Nov  8 22:58:51 1999
@@ -20,6 +20,7 @@
 #include <linux/hfs_fs_sb.h>
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
+#include <linux/unistd.h>
 
 /*================ Forward declarations ================*/
 
@@ -70,7 +71,8 @@
 	hfs_file_truncate,	/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ Variable-like macros ================*/
@@ -544,4 +546,30 @@
 			}
 		}
 	}
+}
+
+long hfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return HFS_NAMELEN;
+	case _PC_NO_TRUNC:
+		return 0;
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return 1;	/* No classical UNIX links */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/hfs/file_cap.c linux-23027p1m1/fs/hfs/file_cap.c
--- linux-23027p1/fs/hfs/file_cap.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/file_cap.c	Mon Nov  8 22:58:51 1999
@@ -84,7 +84,8 @@
 	cap_info_truncate,		/* truncate */
 	NULL,				/* permission */
 	NULL,				/* smap */
-	NULL				/* revalidata */
+	NULL,				/* revalidata */
+	hfs_pathconf,		/* pathconf */
 };
 
 /*================ File-local functions ================*/
diff -ur linux-23027p1/fs/hfs/file_hdr.c linux-23027p1m1/fs/hfs/file_hdr.c
--- linux-23027p1/fs/hfs/file_hdr.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/hfs/file_hdr.c	Mon Nov  8 22:58:51 1999
@@ -86,7 +86,8 @@
 	hdr_truncate,		/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	hfs_pathconf,		/* pathconf */
 };
 
 const struct hfs_hdr_layout hfs_dbl_fil_hdr_layout = {
diff -ur linux-23027p1/fs/hfs/hfs.h linux-23027p1m1/fs/hfs/hfs.h
--- linux-23027p1/fs/hfs/hfs.h	Mon Nov  8 17:25:29 1999
+++ linux-23027p1m1/fs/hfs/hfs.h	Mon Nov  8 22:58:51 1999
@@ -494,6 +494,9 @@
 extern void hfs_extent_adj(struct hfs_fork *);
 extern void hfs_extent_free(struct hfs_fork *);
 
+/* file.c */
+extern long hfs_pathconf(struct inode *, long);
+
 /* mdb.c */
 extern struct hfs_mdb *hfs_mdb_get(hfs_sysmdb, int, hfs_s32);
 extern void hfs_mdb_commit(struct hfs_mdb *, int);
diff -ur linux-23027p1/fs/hpfs/file.c linux-23027p1m1/fs/hpfs/file.c
--- linux-23027p1/fs/hpfs/file.c	Tue Oct 26 21:23:31 1999
+++ linux-23027p1m1/fs/hpfs/file.c	Mon Nov  8 22:58:51 1999
@@ -94,9 +94,10 @@
 	struct page * page_cache = NULL;
 	long status;
 
-	printk("- off: %08x\n", (int)page->offset);
-	pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK;
-	while (pgpos < page->offset) {
+	printk("- off: %Ld\n", (((loff_t)page->index) << PAGE_CACHE_SHIFT));
+	/* Blocks are 512 byte entities */
+	pgpos = (inode->i_blocks - 1) >> (PAGE_CACHE_SHIFT - 9);
+	while (pgpos < page->index) {
 long pgp = pgpos;
 		printk("pgpos: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks);
 		hash = page_hash(&inode->i_data, pgpos);
diff -ur linux-23027p1/fs/isofs/dir.c linux-23027p1m1/fs/isofs/dir.c
--- linux-23027p1/fs/isofs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/isofs/dir.c	Mon Nov  8 22:58:51 1999
@@ -21,11 +21,39 @@
 #include <linux/sched.h>
 #include <linux/locks.h>
 #include <linux/config.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
 static int isofs_readdir(struct file *, void *, filldir_t);
 
+long isofs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		break;	/* This is read-only filesystem! */
+	case _PC_NO_TRUNC:
+		break;	/* This is read-only filesystem! */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32; // FIXME: DVD-XXX ???
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		break;	/* This is read-only filesystem! */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
+
 static struct file_operations isofs_dir_operations =
 {
 	NULL,			/* lseek - default */
@@ -64,7 +92,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	isofs_pathconf,		/* pathconf */
 };
 
 static int isofs_name_translate(char * old, int len, char * new)
diff -ur linux-23027p1/fs/isofs/file.c linux-23027p1m1/fs/isofs/file.c
--- linux-23027p1/fs/isofs/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/isofs/file.c	Mon Nov  8 22:58:51 1999
@@ -17,6 +17,8 @@
 #include <linux/locks.h>
 #include <linux/fs.h>
 
+extern long isofs_pathconf(struct inode *, long);
+
 /*
  * We have mostly NULLs here: the current defaults are OK for
  * the isofs filesystem.
@@ -55,5 +57,6 @@
 	NULL,	       		/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	isofs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/minix/dir.c linux-23027p1m1/fs/minix/dir.c
--- linux-23027p1/fs/minix/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/minix/dir.c	Mon Nov  8 22:58:51 1999
@@ -21,6 +21,7 @@
 }
 
 static int minix_readdir(struct file *, void *, filldir_t);
+extern long minix_pathconf(struct inode *, long);
 
 static struct file_operations minix_dir_operations = {
 	NULL,			/* lseek - default */
@@ -59,7 +60,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	minix_pathconf,		/* pathconf */
 };
 
 static int minix_readdir(struct file * filp,
diff -ur linux-23027p1/fs/minix/file.c linux-23027p1m1/fs/minix/file.c
--- linux-23027p1/fs/minix/file.c	Fri Jul 23 20:30:42 1999
+++ linux-23027p1m1/fs/minix/file.c	Mon Nov  8 22:58:51 1999
@@ -14,6 +14,7 @@
 #include <linux/locks.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -26,6 +27,34 @@
 #include <linux/fs.h>
 #include <linux/minix_fs.h>
 
+long minix_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return inode->i_sb->u.minix_sb.s_namelen;
+
+	case _PC_NO_TRUNC:
+		return 1;		/* UNIX semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return inode->i_sb->u.minix_sb.s_link_max;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
+
 /*
  * Write to a file (through the page cache).
  */
@@ -78,4 +107,5 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	minix_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/minix/symlink.c linux-23027p1m1/fs/minix/symlink.c
--- linux-23027p1/fs/minix/symlink.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/minix/symlink.c	Mon Nov  8 22:58:51 1999
@@ -16,6 +16,7 @@
 
 static int minix_readlink(struct dentry *, char *, int);
 static struct dentry *minix_follow_link(struct dentry *, struct dentry *, unsigned int);
+extern long minix_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -40,7 +41,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	minix_pathconf,		/* pathconf */
 };
 
 static struct dentry * minix_follow_link(struct dentry * dentry,
diff -ur linux-23027p1/fs/msdos/namei.c linux-23027p1m1/fs/msdos/namei.c
--- linux-23027p1/fs/msdos/namei.c	Tue Aug 31 21:23:03 1999
+++ linux-23027p1m1/fs/msdos/namei.c	Mon Nov  8 22:58:51 1999
@@ -583,6 +583,8 @@
 }
 
 
+extern long fat_pathconf(struct inode *, long);
+
 /* The public inode operations for the msdos fs */
 struct inode_operations msdos_dir_inode_operations = {
 	&fat_dir_operations,	/* default directory file-ops */
@@ -605,6 +607,7 @@
 	NULL,			/* permission */
 	NULL,                   /* smap */
 	NULL,                   /* revalidate */
+	fat_pathconf,		/* pathconf */
 };
 
 static void msdos_put_super_callback(struct super_block *sb)
diff -ur linux-23027p1/fs/ncpfs/dir.c linux-23027p1m1/fs/ncpfs/dir.c
--- linux-23027p1/fs/ncpfs/dir.c	Mon Nov  1 20:31:34 1999
+++ linux-23027p1m1/fs/ncpfs/dir.c	Mon Nov  8 22:58:51 1999
@@ -45,6 +45,8 @@
 extern int ncp_symlink(struct inode *, struct dentry *, const char *);
 #endif
 		      
+extern long ncp_pathconf(struct inode *, long);
+
 static struct file_operations ncp_dir_operations =
 {
 	NULL,			/* lseek - default */
@@ -86,6 +88,7 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	ncp_pathconf,		/* pathconf */
 };
 
 static ssize_t 
diff -ur linux-23027p1/fs/ncpfs/file.c linux-23027p1m1/fs/ncpfs/file.c
--- linux-23027p1/fs/ncpfs/file.c	Fri Oct 29 20:53:32 1999
+++ linux-23027p1m1/fs/ncpfs/file.c	Mon Nov  8 22:58:51 1999
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/locks.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
@@ -94,7 +95,7 @@
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	size_t already_read = 0;
-	off_t pos;
+	loff_t pos;
 	size_t bufsize;
 	int error;
 	void* freepage;
@@ -145,7 +146,7 @@
 	/* First read in as much as possible for each bufsize. */
 	while (already_read < count) {
 		int read_this_time;
-		size_t to_read = min(bufsize - (pos % bufsize),
+		size_t to_read = min(bufsize - (pos & (bufsize -1)),
 				  count - already_read);
 
 		error = ncp_read_bounce(NCP_SERVER(inode),
@@ -185,7 +186,7 @@
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	size_t already_written = 0;
-	off_t pos;
+	loff_t pos;
 	size_t bufsize;
 	int errno;
 	void* bouncebuffer;
@@ -222,12 +223,18 @@
 
 	already_written = 0;
 
+	/* Maximum file size: 2G-1 */
+	if (pos >= 0x7fffffffULL)
+		return -EFBIG;
+	if ((pos + count) >= 0x7fffffffULL)
+		count = 0x7fffffffULL - pos;
+
 	bouncebuffer = kmalloc(bufsize, GFP_NFS);
 	if (!bouncebuffer)
 		return -EIO;	/* -ENOMEM */
 	while (already_written < count) {
 		int written_this_time;
-		size_t to_write = min(bufsize - (pos % bufsize),
+		size_t to_write = min(bufsize - (pos & (bufsize -1)),
 				   count - already_written);
 
 		if (copy_from_user(bouncebuffer, buf, to_write)) {
@@ -262,6 +269,34 @@
 	return already_written ? already_written : errno;
 }
 
+ 
+long ncp_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return NCP_MAXNAMELEN; /* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* varies per server.. */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
+
 static struct file_operations ncp_file_operations =
 {
 	NULL,			/* lseek - default */
@@ -298,5 +333,6 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ncp_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/nfs/dir.c linux-23027p1m1/fs/nfs/dir.c
--- linux-23027p1/fs/nfs/dir.c	Sat Oct 30 19:37:26 1999
+++ linux-23027p1m1/fs/nfs/dir.c	Mon Nov  8 22:58:51 1999
@@ -50,6 +50,7 @@
 static int nfs_mknod(struct inode *, struct dentry *, int, int);
 static int nfs_rename(struct inode *, struct dentry *,
 		      struct inode *, struct dentry *);
+extern long nfs_pathconf(struct inode *, long);
 
 static struct file_operations nfs_dir_operations = {
 	NULL,			/* lseek - default */
@@ -86,6 +87,7 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	nfs_revalidate,		/* revalidate */
+	nfs_pathconf,		/* pathconf */
 };
 
 static ssize_t
diff -ur linux-23027p1/fs/nfs/file.c linux-23027p1m1/fs/nfs/file.c
--- linux-23027p1/fs/nfs/file.c	Fri Oct 15 00:22:09 1999
+++ linux-23027p1m1/fs/nfs/file.c	Mon Nov  8 22:58:51 1999
@@ -27,6 +27,7 @@
 #include <linux/pagemap.h>
 #include <linux/lockd/bind.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/segment.h>
@@ -39,6 +40,7 @@
 static ssize_t nfs_file_write(struct file *, const char *, size_t, loff_t *);
 static int  nfs_file_flush(struct file *);
 static int  nfs_fsync(struct file *, struct dentry *dentry);
+extern long nfs_pathconf(struct inode *, long);
 
 static struct file_operations nfs_file_operations = {
 	NULL,			/* lseek - default */
@@ -116,6 +118,11 @@
 		dentry->d_parent->d_name.name, dentry->d_name.name,
 		(unsigned long) count, (unsigned long) *ppos);
 
+	/* Unconditionally allow only up to 2G files */
+	/* FIXME: NFSv3 could allow 64-bit file offsets! */
+	if ((*ppos+1LL) >= 0x7fffffffLL)
+		return -EOVERFLOW;
+
 	result = nfs_revalidate_inode(NFS_DSERVER(dentry), dentry);
 	if (!result)
 		result = generic_file_read(file, buf, count, ppos);
@@ -191,9 +198,16 @@
 	struct inode * inode = dentry->d_inode;
 	ssize_t result;
 
-	dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n",
+	dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name,
-		inode->i_ino, (unsigned long) count, (unsigned long) *ppos);
+		inode->i_ino, (unsigned long) count, *ppos);
+
+	/* Unconditionally allow only up to 2G files */
+	/* FIXME: NFSv3 could allow 64-bit file offsets! */
+	if ((*ppos+1LL) > 0x7fffffffLL) {
+		result = -EOVERFLOW;
+		goto out;
+	}
 
 	result = -EBUSY;
 	if (IS_SWAPFILE(inode))
@@ -224,7 +238,7 @@
 	struct inode * inode = filp->f_dentry->d_inode;
 	int	status = 0;
 
-	dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n",
+	dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n",
 			inode->i_dev, inode->i_ino,
 			fl->fl_type, fl->fl_flags,
 			fl->fl_start, fl->fl_end);
@@ -273,4 +287,32 @@
  out_ok:
 	NFS_CACHEINV(inode);
 	return status;
+}
+
+
+long nfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return -INT_MAX; /* Unknown */
+
+	case _PC_NO_TRUNC:
+		return -INT_MAX; /* Unknown */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;	 /* NFSv3 would allow 64-bit sizes */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return -INT_MAX; /* Unknown */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/nfs/symlink.c linux-23027p1m1/fs/nfs/symlink.c
--- linux-23027p1/fs/nfs/symlink.c	Tue Oct 26 20:41:06 1999
+++ linux-23027p1m1/fs/nfs/symlink.c	Mon Nov  8 22:58:51 1999
@@ -26,6 +26,7 @@
 
 static int nfs_readlink(struct dentry *, char *, int);
 static struct dentry *nfs_follow_link(struct dentry *, struct dentry *, unsigned int);
+extern long nfs_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -50,7 +51,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	nfs_pathconf,		/* pathconf */
 };
 
 /* Symlink caching in the page cache is even more simplistic
diff -ur linux-23027p1/fs/ntfs/fs.c linux-23027p1m1/fs/ntfs/fs.c
--- linux-23027p1/fs/ntfs/fs.c	Fri Aug 27 00:18:06 1999
+++ linux-23027p1m1/fs/ntfs/fs.c	Mon Nov  8 22:58:51 1999
@@ -28,12 +28,40 @@
 #include <linux/nls.h>
 #include <linux/locks.h>
 #include <linux/init.h>
+#include <linux/unistd.h>
 
 /* Forward declarations */
 static struct inode_operations ntfs_dir_inode_operations;
 
 #define ITEM_SIZE 2040
 
+static long ntfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		return 255;
+
+	case _PC_NO_TRUNC:
+		return 0;	/* Non-UNIX semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 /* io functions to user space */
 static void ntfs_putuser(ntfs_io* dest,void *src,ntfs_size_t len)
 {
@@ -447,6 +475,7 @@
 	NULL, /* permission */
 	NULL, /* smap */
 	NULL, /* revalidate */
+	ntfs_pathconf, /* pathconf */
 };
 
 #ifdef CONFIG_NTFS_RW
@@ -630,6 +659,7 @@
 	NULL, /* permission */
 	NULL, /* smap */
 	NULL, /* revalidate */
+	ntfs_pathconf, /* pathconf */
 };
 
 static struct file_operations ntfs_dir_operations = {
@@ -679,6 +709,7 @@
 	NULL, /* permission */
 	NULL, /* smap */
 	NULL, /* revalidate */
+	ntfs_pathconf, /* pathconf */
 };
 
 /* ntfs_read_inode is called by the Virtual File System (the kernel layer that
diff -ur linux-23027p1/fs/pipe.c linux-23027p1m1/fs/pipe.c
--- linux-23027p1/fs/pipe.c	Wed Sep  8 21:20:20 1999
+++ linux-23027p1m1/fs/pipe.c	Mon Nov  8 22:58:51 1999
@@ -9,6 +9,7 @@
 #include <linux/poll.h>
 #include <linux/malloc.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -529,9 +530,10 @@
 	NULL
 };
 
+static struct inode_operations pipe_inode_operations;
+
 static struct inode * get_pipe_inode(void)
 {
-	extern struct inode_operations pipe_inode_operations;
 	struct inode *inode = get_empty_inode();
 	unsigned long page;
 
@@ -575,7 +577,14 @@
 	return NULL;
 }
 
-struct inode_operations pipe_inode_operations = {
+long pipe_pathconf(struct inode *inode, long option)
+{
+	if (option == _PC_PIPE_BUF)
+		return PIPE_BUF;
+	return -EINVAL;
+}
+
+static struct inode_operations pipe_inode_operations = {
 	&rdwr_pipe_fops,
 	NULL,			/* create */
 	NULL,			/* lookup */
@@ -595,7 +604,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	pipe_pathconf,		/* pathconf */
 };
 
 int do_pipe(int *fd)
diff -ur linux-23027p1/fs/qnx4/dir.c linux-23027p1m1/fs/qnx4/dir.c
--- linux-23027p1/fs/qnx4/dir.c	Tue Jul  6 05:59:55 1999
+++ linux-23027p1m1/fs/qnx4/dir.c	Mon Nov  8 22:58:51 1999
@@ -20,6 +20,8 @@
 
 #include <asm/segment.h>
 
+extern long qnx4_pathconf(struct inode *, long);
+
 static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir);
 
 static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
@@ -126,5 +128,6 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	qnx4_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/qnx4/file.c linux-23027p1m1/fs/qnx4/file.c
--- linux-23027p1/fs/qnx4/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/qnx4/file.c	Mon Nov  8 22:58:51 1999
@@ -25,6 +25,7 @@
 #include <linux/locks.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
+#include <linux/unistd.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -144,8 +145,34 @@
 }
 #endif
 
+long qnx4_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return QNX4_NAME_MAX;
+	case _PC_NO_TRUNC:
+	  return 0;		/* silent truncation */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 /*
- * We have moostly NULL's here: the current defaults are ok for
+ * We have mostly NULL's here: the current defaults are ok for
  * the qnx4 filesystem.
  */
 static struct file_operations qnx4_file_operations =
@@ -200,7 +227,8 @@
 #endif
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	qnx4_pathconf,		/* pathconf */
 };
 
 static int qnx4_readpage(struct file *file, struct page *page)
diff -ur linux-23027p1/fs/qnx4/symlinks.c linux-23027p1m1/fs/qnx4/symlinks.c
--- linux-23027p1/fs/qnx4/symlinks.c	Tue Jul  6 05:59:55 1999
+++ linux-23027p1m1/fs/qnx4/symlinks.c	Mon Nov  8 22:58:51 1999
@@ -25,6 +25,7 @@
 
 static int qnx4_readlink(struct dentry *, char *, int);
 static struct dentry *qnx4_follow_link(struct dentry *, struct dentry *, unsigned int follow);
+extern long qnx4_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -50,7 +51,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	qnx4_pathconf,		/* pathconf */
 };
 
 static struct dentry *qnx4_follow_link(struct dentry *dentry,
diff -ur linux-23027p1/fs/romfs/inode.c linux-23027p1m1/fs/romfs/inode.c
--- linux-23027p1/fs/romfs/inode.c	Wed Oct 27 01:03:19 1999
+++ linux-23027p1m1/fs/romfs/inode.c	Mon Nov  8 22:58:51 1999
@@ -58,6 +58,7 @@
 #include <linux/locks.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -486,6 +484,32 @@
 	return dentry;
 }
 
+static long romfs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+		break;	/* This is read-only filesystem! */
+	case _PC_NO_TRUNC:
+		break;	/* This is read-only filesystem! */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+		return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		break;	/* This is read-only filesystem! */
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+		break;
+	default:
+		break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 /* Mapping from our types to the kernel */
 
 static struct file_operations romfs_file_operations = {
@@ -525,7 +549,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	romfs_pathconf,		/* pathconf */
 };
 
 static struct file_operations romfs_dir_operations = {
@@ -542,7 +567,7 @@
 	NULL,			/* fsync */
 	NULL,			/* fasync */
 	NULL,			/* check_media_change */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
 };
 
 /* Merged dir/symlink op table.  readdir/lookup/readlink/follow_link
@@ -569,7 +594,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	romfs_pathconf,		/* pathconf */
 };
 
 static struct inode_operations romfs_link_inode_operations = {
@@ -592,7 +618,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	romfs_pathconf,		/* pathconf */
 };
 
 static mode_t romfs_modemap[] =
@@ -678,7 +705,7 @@
 	NULL,			/* notify change */
 	romfs_put_super,	/* put super */
 	NULL,			/* write super */
-	romfs_statfs,		/* statfs */
+	romfs_statvfs,		/* statvfs */
 	NULL			/* remount */
 };
 
diff -ur linux-23027p1/fs/smbfs/dir.c linux-23027p1m1/fs/smbfs/dir.c
--- linux-23027p1/fs/smbfs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/smbfs/dir.c	Mon Nov  8 22:58:52 1999
@@ -29,6 +29,8 @@
 static int smb_unlink(struct inode *, struct dentry *);
 static int smb_rename(struct inode *, struct dentry *,
 		      struct inode *, struct dentry *);
+extern long smb_pathconf(struct inode *, long);
+
 
 static struct file_operations smb_dir_operations =
 {
@@ -67,6 +69,7 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	smb_revalidate_inode,	/* revalidate */
+	smb_pathconf,		/* pathconf */
 };
 
 static ssize_t
diff -ur linux-23027p1/fs/smbfs/file.c linux-23027p1m1/fs/smbfs/file.c
--- linux-23027p1/fs/smbfs/file.c	Sat Oct 30 02:45:32 1999
+++ linux-23027p1m1/fs/smbfs/file.c	Mon Nov  8 22:58:52 1999
@@ -15,6 +15,7 @@
 #include <linux/malloc.h>
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -367,6 +384,33 @@
 	return error;
 }
 
+ 
+long smb_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return SMB_MAXNAMELEN;
+	case _PC_NO_TRUNC:
+	  return 1;		/* UNIX-like semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 static struct file_operations smb_file_operations =
 {
 	NULL,			/* lseek - default */
@@ -408,4 +452,5 @@
 	smb_file_permission,	/* permission */
 	NULL,			/* smap */
 	smb_revalidate_inode,	/* revalidate */
+	smb_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/stat.c linux-23027p1m1/fs/stat.c
--- linux-23027p1/fs/stat.c	Mon Aug 23 21:15:53 1999
+++ linux-23027p1m1/fs/stat.c	Mon Nov  8 22:58:52 1999
@@ -8,10 +8,22 @@
 #include <linux/errno.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
 /*
+ *  Large File Summit rules tell that fstat() with insufficient st_size
+ *  value space shall fail with  errno=EOVERFLOW,  while other *stat()
+ *  calls just return some arbitary value (e.g. MAXINT) at the same field.
+ *  This constant tells to behave differently.
+ *
+ */
+#define  all_fail_alike_fstat  0
+
+
+
+/*
  * Revalidate the inode. This is required for proper NFS attribute caching.
  */
 static __inline__ int
@@ -28,7 +40,7 @@
 
 /*
  * For backward compatibility?  Maybe this should be moved
- * into arch/i386 instead?
+ * into arch/i386 instead?  (and to m68k ???)
  */
 static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
 {
@@ -57,7 +69,12 @@
 
 #endif
 
-static int cp_new_stat(struct inode * inode, struct stat * statbuf)
+/* "No lie" policy yields EOVERFLOW if file size exceeds
+   a value which is presentable in field st_size (or st_blocks,
+   or st_ino). But then the file will not appear in the directory
+   listing at all before we have stat64() syscalls in use.. */
+
+static int cp_new_stat(struct inode * inode, struct stat * statbuf, int f)
 {
 	struct stat tmp;
 	unsigned int blocks, indirect;
@@ -65,12 +82,29 @@
 	memset(&tmp, 0, sizeof(tmp));
 	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
 	tmp.st_ino = inode->i_ino;
+	if (tmp.st_ino != inode->i_ino) {
+		if (f || all_fail_alike_fstat)
+			return -EOVERFLOW; /* See LFS spec: 2.2.1.14
+					      Xstat() shall fail with
+					      EOVERFLOW. */
+	  tmp.st_ino = -1;
+	}
 	tmp.st_mode = inode->i_mode;
 	tmp.st_nlink = inode->i_nlink;
 	tmp.st_uid = inode->i_uid;
 	tmp.st_gid = inode->i_gid;
 	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+	/* large-file stat() problem...
+	   If your file size is 4G-1, it *propably*
+	   is over 4G in a 32-bit system... */
 	tmp.st_size = inode->i_size;
+	if (inode->i_size != tmp.st_size) {
+		if (f || all_fail_alike_fstat)
+			return -EOVERFLOW; /* See LFS spec: 2.2.1.14
+					      Xstat() shall fail with
+					      EOVERFLOW. */
+		tmp.st_size = ULONG_MAX;
+	}
 	tmp.st_atime = inode->i_atime;
 	tmp.st_mtime = inode->i_mtime;
 	tmp.st_ctime = inode->i_ctime;
@@ -110,6 +144,15 @@
 		tmp.st_blocks = inode->i_blocks;
 		tmp.st_blksize = inode->i_blksize;
 	}
+#if BITS_PER_LONG < 64
+	if (tmp.st_blocks != inode->i_blocks) {
+		if (f || all_fail_alike_fstat)
+			return -EOVERFLOW; /* See LFS spec: 2.2.1.14
+					      Xstat() shall fail with
+					      EOVERFLOW. */
+		tmp.st_blocks = ULONG_MAX;
+	}
+#endif
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
@@ -152,7 +195,7 @@
 	if (!IS_ERR(dentry)) {
 		error = do_revalidate(dentry);
 		if (!error)
-			error = cp_new_stat(dentry->d_inode, statbuf);
+			error = cp_new_stat(dentry->d_inode, statbuf, 0);
 
 		dput(dentry);
 	}
@@ -200,7 +243,7 @@
 	if (!IS_ERR(dentry)) {
 		error = do_revalidate(dentry);
 		if (!error)
-			error = cp_new_stat(dentry->d_inode, statbuf);
+			error = cp_new_stat(dentry->d_inode, statbuf, 0);
 
 		dput(dentry);
 	}
@@ -247,7 +290,7 @@
 
 		err = do_revalidate(dentry);
 		if (!err)
-			err = cp_new_stat(dentry->d_inode, statbuf);
+			err = cp_new_stat(dentry->d_inode, statbuf, 1);
 		fput(f);
 	}
 	unlock_kernel();
@@ -279,4 +322,249 @@
 	}
 	unlock_kernel();
 	return error;
+}
+
+
+/* ---------- LFS-64 ----------- */
+
+static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf)
+{
+	struct stat64 tmp;
+	unsigned int blocks, indirect;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
+	tmp.st_ino = inode->i_ino;
+	tmp.st_mode = inode->i_mode;
+	tmp.st_nlink = inode->i_nlink;
+	tmp.st_uid = inode->i_uid;
+	tmp.st_gid = inode->i_gid;
+	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+	tmp.st_atime = inode->i_atime;
+	tmp.st_mtime = inode->i_mtime;
+	tmp.st_ctime = inode->i_ctime;
+	tmp.st_size = inode->i_size;
+/*
+ * st_blocks and st_blksize are approximated with a simple algorithm if
+ * they aren't supported directly by the filesystem. The minix and msdos
+ * filesystems don't keep track of blocks, so they would either have to
+ * be counted explicitly (by delving into the file itself), or by using
+ * this simple algorithm to get a reasonable (although not 100% accurate)
+ * value.
+ */
+
+/*
+ * Use minix fs values for the number of direct and indirect blocks.  The
+ * count is now exact for the minix fs except that it counts zero blocks.
+ * Everything is in units of BLOCK_SIZE until the assignment to
+ * tmp.st_blksize.
+ */
+#define D_B   7
+#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
+
+	if (!inode->i_blksize) {
+		blocks = (tmp.st_size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
+		if (blocks > D_B) {
+			indirect = (blocks - D_B + I_B - 1) / I_B;
+			blocks += indirect;
+			if (indirect > 1) {
+				indirect = (indirect - 1 + I_B - 1) / I_B;
+				blocks += indirect;
+				if (indirect > 1)
+					blocks++;
+			}
+		}
+		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
+		tmp.st_blksize = BLOCK_SIZE;
+	} else {
+		tmp.st_blocks = inode->i_blocks;
+		tmp.st_blksize = inode->i_blksize;
+	}
+	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_newstat64(char * filename, struct stat64 * statbuf, long flags)
+{
+	struct dentry * dentry;
+	int error;
+
+	lock_kernel();
+	dentry = namei(filename);
+
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		error = do_revalidate(dentry);
+		if (!error)
+			error = cp_new_stat64(dentry->d_inode, statbuf);
+
+		dput(dentry);
+	}
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage long sys_newlstat64(char * filename, struct stat64 * statbuf, long flags)
+{
+	struct dentry * dentry;
+	int error;
+
+	lock_kernel();
+	dentry = lnamei(filename);
+
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		error = do_revalidate(dentry);
+		if (!error)
+			error = cp_new_stat64(dentry->d_inode, statbuf);
+
+		dput(dentry);
+	}
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage long sys_newfstat64(unsigned long fd, struct stat64 * statbuf, long flags)
+{
+	struct file * f;
+	int err = -EBADF;
+
+	lock_kernel();
+	f = fget(fd);
+	if (f) {
+		struct dentry * dentry = f->f_dentry;
+
+		err = do_revalidate(dentry);
+		if (!err)
+			err = cp_new_stat64(dentry->d_inode, statbuf);
+		fput(f);
+	}
+	unlock_kernel();
+	return err;
+}
+
+
+
+/*
+ * POSIX pathconf()
+ *
+ * return value rules differ from sysconf(); If no explicite limit
+ * is in effect for given option,  pathconf()  shall return -1 without
+ * touching errno.  If the failure is anywhere else, errors like EINVAL,
+ * EACCESS, ENOENT,  etc. are possible..
+ *
+ * Returning ``-1'' without errno is indicated by returning ``-INT_MAX''
+ */
+
+extern long pipe_pathconf(struct inode *inode, long option);
+extern __u32 sysctl_wmem_max;
+
+static long dpathconf(struct dentry *dentry, long option)
+{
+	int (*pathconf)(struct inode*, int);
+	umode_t mode = dentry->d_inode->i_mode;
+
+	switch (option) {
+	case _PC_ASYNC_IO:	/* POSIX.4: TTY only (per Solaris) */
+	case _PC_PRIO_IO:
+	case _PC_MAX_CANON:	/* POSIX.1: TTY only */
+	case _PC_MAX_INPUT:
+	case _PC_VDISABLE:
+		if (!S_ISCHR(mode)) /* CHAR devices -- at least */
+			return -EINVAL;
+		break;
+
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	case _PC_NO_TRUNC:
+		if (!S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	case _PC_PATH_MAX:
+		if (!S_ISDIR(mode))
+			return -EINVAL;
+		return PATH_MAX;
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+		if (!S_ISREG(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	case _PC_PIPE_BUF:	/* POSIX.1: Pipes & dirs only */
+		if (!S_ISFIFO(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		/* This direct call to pipe_pathconf() is done this
+		   way, because with named pipes the names may exist
+		   in some remote directories, but the pipes them-
+		   selves live only in the local system kernel */
+		return pipe_pathconf(dentry->d_inode, option);
+
+	case _PC_SOCK_MAXBUF:	/* POSIX.1g: fpathconf() */
+		if (!S_ISSOCK(mode))
+			return -EINVAL;
+		return sysctl_wmem_max;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+		if (!S_ISREG(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only */
+		/* Solaris: Dirs ok too! */
+		if (!S_ISREG(mode) && !S_ISDIR(mode))
+			return -EINVAL;
+		break;
+
+	default:		/* Eh ?? */
+		return -EINVAL;
+	}
+
+	pathconf = dentry->d_inode->i_op->pathconf;
+	if (pathconf)
+		return pathconf(dentry->d_inode, option);
+
+	return -EINVAL;	/* No pathconf, no direct processing! */
+}
+
+asmlinkage long sys_pathconf(char *pathname, long option)
+{
+	struct dentry * dentry;
+	int error;
+
+	lock_kernel();
+	dentry = namei(pathname);
+
+	error = PTR_ERR(dentry);
+	if (!IS_ERR(dentry)) {
+		error = do_revalidate(dentry);
+		if (!error)
+			error = dpathconf(dentry, option);
+		dput(dentry);
+	}
+	unlock_kernel();
+	return error;
+}
+
+/*
+ * POSIX fpathconf() -- pathconf() with 'fd'
+ */
+
+asmlinkage long sys_fpathconf(long fd, long option)
+{
+	struct file * f;
+	int err;
+
+	lock_kernel();
+	f = fget(fd);
+	if (f) {
+		struct dentry * dentry = f->f_dentry;
+		
+		err = do_revalidate(dentry);
+		if (!err)
+			err = dpathconf(dentry, option);
+		fput(f);
+	} else
+		err = -EBADF;
+	unlock_kernel();
+	return err;
 }
diff -ur linux-23027p1/fs/sysv/dir.c linux-23027p1m1/fs/sysv/dir.c
--- linux-23027p1/fs/sysv/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/sysv/dir.c	Mon Nov  8 22:58:52 1999
@@ -18,6 +18,7 @@
 #include <linux/sysv_fs.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -28,6 +29,7 @@
 }
 
 static int sysv_readdir(struct file *, void *, filldir_t);
+extern long sysv_pathconf(struct inode *inode, long option);
 
 static struct file_operations sysv_dir_operations = {
 	NULL,			/* lseek - default */
@@ -66,7 +68,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	sysv_pathconf,		/* pathconf */
 };
 
 static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
@@ -114,4 +117,30 @@
 		brelse(bh);
 	}
 	return 0;
+}
+
+long sysv_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return SYSV_NAMELEN;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return !inode->i_sb->sv_truncate;
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return inode->i_sb->sv_link_max;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
 }
diff -ur linux-23027p1/fs/sysv/file.c linux-23027p1m1/fs/sysv/file.c
--- linux-23027p1/fs/sysv/file.c	Tue Jul  6 06:35:18 1999
+++ linux-23027p1m1/fs/sysv/file.c	Mon Nov  8 22:58:52 1999
@@ -40,6 +40,8 @@
 				  ppos, block_write_partial_page);
 }
 
+extern long sysv_pathconf(struct inode *, long);
+
 /*
  * We have mostly NULLs here: the current defaults are OK for
  * the coh filesystem.
@@ -81,5 +83,6 @@
 	sysv_truncate,		/* truncate */
 	NULL,   		/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	sysv_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/sysv/symlink.c linux-23027p1m1/fs/sysv/symlink.c
--- linux-23027p1/fs/sysv/symlink.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/sysv/symlink.c	Mon Nov  8 22:58:52 1999
@@ -22,6 +22,7 @@
 
 static int sysv_readlink(struct dentry *, char *, int);
 static struct dentry *sysv_follow_link(struct dentry *, struct dentry *, unsigned int);
+extern long sysv_pathconf(struct inode *, long);
 
 /*
  * symlinks can't do much...
@@ -46,7 +47,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	sysv_pathconf,		/* pathconf */
 };
 
 static struct dentry *sysv_follow_link(struct dentry * dentry,
diff -ur linux-23027p1/fs/ufs/dir.c linux-23027p1m1/fs/ufs/dir.c
--- linux-23027p1/fs/ufs/dir.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/ufs/dir.c	Mon Nov  8 22:58:52 1999
@@ -18,6 +18,7 @@
 
 #include "swab.h"
 #include "util.h"
+#include <linux/unistd.h>
 
 #undef UFS_DIR_DEBUG
 
@@ -168,7 +169,7 @@
 		error_msg = "inode out of bounds";
 
 	if (error_msg != NULL)
-		ufs_error (sb, function, "bad entry in directory #%lu, size %lu: %s - "
+		ufs_error (sb, function, "bad entry in directory #%lu, size %Lu: %s - "
 			    "offset=%lu, inode=%lu, reclen=%d, namlen=%d",
 			    dir->i_ino, dir->i_size, error_msg, offset,
 			    (unsigned long) SWAB32(de->d_ino),
@@ -177,6 +178,32 @@
 	return (error_msg == NULL ? 1 : 0);
 }
 
+long ufs_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return UFS_MAXNAMLEN; /* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* UNIX semantics */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 64; /* FIXME: L-F-S:  mount-option: nolargefiles ? */
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return UFS_LINK_MAX;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
+
 static struct file_operations ufs_dir_operations = {
 	NULL,			/* lseek */
 	NULL,			/* read */
@@ -214,5 +241,6 @@
 	NULL,			/* truncate */
 	ufs_permission,		/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ufs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/ufs/file.c linux-23027p1m1/fs/ufs/file.c
--- linux-23027p1/fs/ufs/file.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/ufs/file.c	Mon Nov  8 22:58:52 1999
@@ -137,6 +137,8 @@
 	NULL			/* revalidate */
 };
 
+extern long ufs_pathconf(struct inode *, long);
+
 struct inode_operations ufs_file_inode_operations = {
 	&ufs_file_operations,/* default file operations */
 	NULL,			/* create */
@@ -157,5 +159,6 @@
 	ufs_truncate,		/* truncate */
 	NULL, 			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ufs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/ufs/symlink.c linux-23027p1m1/fs/ufs/symlink.c
--- linux-23027p1/fs/ufs/symlink.c	Sun Jun 27 20:10:41 1999
+++ linux-23027p1m1/fs/ufs/symlink.c	Mon Nov  8 22:58:52 1999
@@ -116,6 +116,8 @@
 	return i;
 }
 
+extern long ufs_pathconf(struct inode *, long);
+
 struct inode_operations ufs_symlink_inode_operations = {
 	NULL,			/* no file-operations */
 	NULL,			/* create */
@@ -136,5 +138,6 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	ufs_pathconf,		/* pathconf */
 };
diff -ur linux-23027p1/fs/umsdos/dir.c linux-23027p1m1/fs/umsdos/dir.c
--- linux-23027p1/fs/umsdos/dir.c	Mon Aug  9 21:43:49 1999
+++ linux-23027p1m1/fs/umsdos/dir.c	Mon Nov  8 22:58:52 1999
@@ -16,6 +16,7 @@
 #include <linux/limits.h>
 #include <linux/umsdos_fs.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 #include <asm/uaccess.h>
 
@@ -801,6 +802,32 @@
 	goto out_free;
 }	
 
+ 
+static long umsdos_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return 256;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
 
 static struct file_operations umsdos_dir_operations =
 {
@@ -839,4 +866,5 @@
 	NULL,			/* permission */
 	NULL,			/* smap */
 	NULL,			/* revalidate */
+	umsdos_pathconf,	/* pathconf */
 };
diff -ur linux-23027p1/fs/vfat/namei.c linux-23027p1m1/fs/vfat/namei.c
--- linux-23027p1/fs/vfat/namei.c	Mon Aug  9 21:43:49 1999
+++ linux-23027p1m1/fs/vfat/namei.c	Mon Nov  8 22:58:52 1999
@@ -23,6 +23,7 @@
 #include <linux/stat.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/unistd.h>
 
 #include "../fat/msbuffer.h"
 
@@ -1187,6 +1188,31 @@
 
 }
 
+static long vfat_pathconf(struct inode *inode, long option)
+{
+	switch (option) {
+	case _PC_NAME_MAX:	/* POSIX.1: Directory only */
+	  return 256;	/* name component max length */
+	case _PC_NO_TRUNC:
+	  return 1;		/* Semantics ??? */
+
+	case _PC_FILESIZEBITS:	/* LFS: Regular files, and dirs */
+	  return 32;
+
+	case _PC_LINK_MAX:	/* POSIX.1: regular files and dirs */
+	  return 1;
+
+	case _PC_CHOWN_RESTRICTED: /* POSIX.1: Any file, any dir */
+	  break;		/* FIXME: some mount-option ??? */
+
+	case _PC_SYNC_IO:	/* POSIX.4: Regular files only ? */
+	case _PC_ASYNC_IO: /* TTY only ?? */
+	  break;
+	default:
+	  break;
+	}
+	return -EINVAL; /* Unknown thing! */
+}
 
 /* Public inode operations for the VFAT fs */
 struct inode_operations vfat_dir_inode_operations = {
@@ -1209,7 +1235,8 @@
 	NULL,			/* truncate */
 	NULL,			/* permission */
 	NULL,			/* smap */
-	NULL			/* revalidate */
+	NULL,			/* revalidate */
+	vfat_pathconf,		/* pathconf */
 };
 
 struct super_block *vfat_read_super(struct super_block *sb,void *data,
diff -ur linux-23027p1/include/linux/fs.h linux-23027p1m1/include/linux/fs.h
--- linux-23027p1/include/linux/fs.h	Mon Nov  8 22:57:35 1999
+++ linux-23027p1m1/include/linux/fs.h	Mon Nov  8 22:58:52 1999
@@ -655,6 +686,7 @@
 	int (*permission) (struct inode *, int);
 	int (*smap) (struct inode *,int);
 	int (*revalidate) (struct dentry *);
+	long (*pathconf) (struct inode *, long option);
 };
 
 struct super_operations {
diff -ur linux-23027p1/include/linux/msdos_fs.h linux-23027p1m1/include/linux/msdos_fs.h
--- linux-23027p1/include/linux/msdos_fs.h	Mon Nov  8 14:14:22 1999
+++ linux-23027p1m1/include/linux/msdos_fs.h	Mon Nov  8 22:58:52 1999
@@ -270,6 +270,7 @@
 extern ssize_t fat_file_read(struct file *, char *, size_t, loff_t *);
 extern ssize_t fat_file_write(struct file *, const char *, size_t, loff_t *);
 extern void fat_truncate(struct inode *inode);
+extern long fat_pathconf(struct inode *, long);
 
 /* mmap.c */
 extern int fat_mmap(struct file *, struct vm_area_struct *);
diff -ur linux-23027p1/include/linux/unistd.h linux-23027p1m1/include/linux/unistd.h
--- linux-23027p1/include/linux/unistd.h	Fri Oct 29 23:41:57 1999
+++ linux-23027p1m1/include/linux/unistd.h	Mon Nov  8 22:58:52 1999
@@ -8,4 +8,350 @@
  */
 #include <asm/unistd.h>
 
+
+/* ---------- KERNEL SPACE NEEDS THESE FOR  pathconf() AND sysconf()
+              THINGS AT ALL PLATFORMS  ----------------------------- */
+/* ---------- THESE ARE PICKED FROM GLIBC 2.1(pre) HEADERFILES ----- */
+/* ---------- VALUES FOR confstr ARE REMOVED ----------------------- */
+
+/* `sysconf', `pathconf', and `confstr' NAME values.  Generic version.
+   Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifdef __KERNEL__
+
+/* Values for the NAME argument to `pathconf' and `fpathconf'.  */
+enum
+  {
+    _PC_LINK_MAX	= 0,
+#define	_PC_LINK_MAX			_PC_LINK_MAX
+    _PC_MAX_CANON	= 1,
+#define	_PC_MAX_CANON			_PC_MAX_CANON
+    _PC_MAX_INPUT	= 2,
+#define	_PC_MAX_INPUT			_PC_MAX_INPUT
+    _PC_NAME_MAX	= 3,
+#define	_PC_NAME_MAX			_PC_NAME_MAX
+    _PC_PATH_MAX	= 4,
+#define	_PC_PATH_MAX			_PC_PATH_MAX
+    _PC_PIPE_BUF	= 5,
+#define	_PC_PIPE_BUF			_PC_PIPE_BUF
+    _PC_CHOWN_RESTRICTED = 6,
+#define	_PC_CHOWN_RESTRICTED		_PC_CHOWN_RESTRICTED
+    _PC_NO_TRUNC	= 7,
+#define	_PC_NO_TRUNC			_PC_NO_TRUNC
+    _PC_VDISABLE	= 8,
+#define _PC_VDISABLE			_PC_VDISABLE
+    _PC_SYNC_IO		= 9,
+#define	_PC_SYNC_IO			_PC_SYNC_IO
+    _PC_ASYNC_IO	= 10,
+#define	_PC_ASYNC_IO			_PC_ASYNC_IO
+    _PC_PRIO_IO		= 11,
+#define	_PC_PRIO_IO			_PC_PRIO_IO
+    _PC_SOCK_MAXBUF	= 12,
+#define	_PC_SOCK_MAXBUF			_PC_SOCK_MAXBUF
+    _PC_FILESIZEBITS	= 13
+#define _PC_FILESIZEBITS		_PC_FILESIZEBITS
+  };
+
+/* Values for the argument to `sysconf'.  */
+enum
+  {
+    _SC_ARG_MAX			= 0,
+#define	_SC_ARG_MAX			_SC_ARG_MAX
+    _SC_CHILD_MAX		= 1,
+#define	_SC_CHILD_MAX			_SC_CHILD_MAX
+    _SC_CLK_TCK			= 2,
+#define	_SC_CLK_TCK			_SC_CLK_TCK
+    _SC_NGROUPS_MAX		= 3,
+#define	_SC_NGROUPS_MAX			_SC_NGROUPS_MAX
+    _SC_OPEN_MAX		= 4,
+#define	_SC_OPEN_MAX			_SC_OPEN_MAX
+    _SC_STREAM_MAX		= 5,
+#define	_SC_STREAM_MAX			_SC_STREAM_MAX
+    _SC_TZNAME_MAX		= 6,
+#define	_SC_TZNAME_MAX			_SC_TZNAME_MAX
+    _SC_JOB_CONTROL		= 7,
+#define	_SC_JOB_CONTROL			_SC_JOB_CONTROL
+    _SC_SAVED_IDS		= 8,
+#define	_SC_SAVED_IDS			_SC_SAVED_IDS
+    _SC_REALTIME_SIGNALS	= 9,
+#define	_SC_REALTIME_SIGNALS		_SC_REALTIME_SIGNALS
+    _SC_PRIORITY_SCHEDULING	= 10,
+#define	_SC_PRIORITY_SCHEDULING		_SC_PRIORITY_SCHEDULING
+    _SC_TIMERS			= 11,
+#define	_SC_TIMERS			_SC_TIMERS
+    _SC_ASYNCHRONOUS_IO		= 12,
+#define	_SC_ASYNCHRONOUS_IO		_SC_ASYNCHRONOUS_IO
+    _SC_PRIORITIZED_IO		= 13,
+#define	_SC_PRIORITIZED_IO		_SC_PRIORITIZED_IO
+    _SC_SYNCHRONIZED_IO		= 14,
+#define	_SC_SYNCHRONIZED_IO		_SC_SYNCHRONIZED_IO
+    _SC_FSYNC			= 15,
+#define	_SC_FSYNC			_SC_FSYNC
+    _SC_MAPPED_FILES		= 16,
+#define	_SC_MAPPED_FILES		_SC_MAPPED_FILES
+    _SC_MEMLOCK			= 17,
+#define	_SC_MEMLOCK			_SC_MEMLOCK
+    _SC_MEMLOCK_RANGE		= 18,
+#define	_SC_MEMLOCK_RANGE		_SC_MEMLOCK_RANGE
+    _SC_MEMORY_PROTECTION	= 19,
+#define	_SC_MEMORY_PROTECTION		_SC_MEMORY_PROTECTION
+    _SC_MESSAGE_PASSING		= 20,
+#define	_SC_MESSAGE_PASSING		_SC_MESSAGE_PASSING
+    _SC_SEMAPHORES		= 21,
+#define	_SC_SEMAPHORES			_SC_SEMAPHORES
+    _SC_SHARED_MEMORY_OBJECTS	= 22,
+#define	_SC_SHARED_MEMORY_OBJECTS	_SC_SHARED_MEMORY_OBJECTS
+    _SC_AIO_LISTIO_MAX		= 23,
+#define	_SC_AIO_LISTIO_MAX		_SC_AIO_LISTIO_MAX
+    _SC_AIO_MAX			= 24,
+#define	_SC_AIO_MAX			_SC_AIO_MAX
+    _SC_AIO_PRIO_DELTA_MAX	= 25,
+#define	_SC_AIO_PRIO_DELTA_MAX		_SC_AIO_PRIO_DELTA_MAX
+    _SC_DELAYTIMER_MAX		= 26,
+#define	_SC_DELAYTIMER_MAX		_SC_DELAYTIMER_MAX
+    _SC_MQ_OPEN_MAX		= 27,
+#define	_SC_MQ_OPEN_MAX			_SC_MQ_OPEN_MAX
+    _SC_MQ_PRIO_MAX		= 28,
+#define	_SC_MQ_PRIO_MAX			_SC_MQ_PRIO_MAX
+    _SC_VERSION			= 29,
+#define	_SC_VERSION			_SC_VERSION
+    _SC_PAGESIZE		= 30,
+#define	_SC_PAGESIZE			_SC_PAGESIZE
+#define	_SC_PAGE_SIZE			_SC_PAGESIZE
+    _SC_RTSIG_MAX		= 31,
+#define	_SC_RTSIG_MAX			_SC_RTSIG_MAX
+    _SC_SEM_NSEMS_MAX		= 32,
+#define	_SC_SEM_NSEMS_MAX		_SC_SEM_NSEMS_MAX
+    _SC_SEM_VALUE_MAX		= 33,
+#define	_SC_SEM_VALUE_MAX		_SC_SEM_VALUE_MAX
+    _SC_SIGQUEUE_MAX		= 34,
+#define	_SC_SIGQUEUE_MAX		_SC_SIGQUEUE_MAX
+    _SC_TIMER_MAX		= 35,
+#define	_SC_TIMER_MAX			_SC_TIMER_MAX
+
+    /* Values for the argument to `sysconf'
+       corresponding to _POSIX2_* symbols.  */
+    _SC_BC_BASE_MAX		= 36,
+#define	_SC_BC_BASE_MAX			_SC_BC_BASE_MAX
+    _SC_BC_DIM_MAX		= 37,
+#define	_SC_BC_DIM_MAX			_SC_BC_DIM_MAX
+    _SC_BC_SCALE_MAX		= 38,
+#define	_SC_BC_SCALE_MAX		_SC_BC_SCALE_MAX
+    _SC_BC_STRING_MAX		= 39,
+#define	_SC_BC_STRING_MAX		_SC_BC_STRING_MAX
+    _SC_COLL_WEIGHTS_MAX	= 40,
+#define	_SC_COLL_WEIGHTS_MAX		_SC_COLL_WEIGHTS_MAX
+    _SC_EQUIV_CLASS_MAX		= 41,
+#define	_SC_EQUIV_CLASS_MAX		_SC_EQUIV_CLASS_MAX
+    _SC_EXPR_NEST_MAX		= 42,
+#define	_SC_EXPR_NEST_MAX		_SC_EXPR_NEST_MAX
+    _SC_LINE_MAX		= 43,
+#define	_SC_LINE_MAX			_SC_LINE_MAX
+    _SC_RE_DUP_MAX		= 44,
+#define	_SC_RE_DUP_MAX			_SC_RE_DUP_MAX
+    _SC_CHARCLASS_NAME_MAX	= 45,
+#define	_SC_CHARCLASS_NAME_MAX		_SC_CHARCLASS_NAME_MAX
+
+    _SC_2_VERSION		= 46,
+#define	_SC_2_VERSION			_SC_2_VERSION
+    _SC_2_C_BIND		= 47,
+#define	_SC_2_C_BIND			_SC_2_C_BIND
+    _SC_2_C_DEV			= 48,
+#define	_SC_2_C_DEV			_SC_2_C_DEV
+    _SC_2_FORT_DEV		= 49,
+#define	_SC_2_FORT_DEV			_SC_2_FORT_DEV
+    _SC_2_FORT_RUN		= 50,
+#define	_SC_2_FORT_RUN			_SC_2_FORT_RUN
+    _SC_2_SW_DEV		= 51,
+#define	_SC_2_SW_DEV			_SC_2_SW_DEV
+    _SC_2_LOCALEDEF		= 52,
+#define	_SC_2_LOCALEDEF			_SC_2_LOCALEDEF
+
+    _SC_PII			= 53,
+#define	_SC_PII				_SC_PII
+    _SC_PII_XTI			= 54,
+#define	_SC_PII_XTI			_SC_PII_XTI
+    _SC_PII_SOCKET		= 55,
+#define	_SC_PII_SOCKET			_SC_PII_SOCKET
+    _SC_PII_INTERNET		= 56,
+#define	_SC_PII_INTERNET		_SC_PII_INTERNET
+    _SC_PII_OSI			= 57,
+#define	_SC_PII_OSI			_SC_PII_OSI
+    _SC_POLL			= 58,
+#define	_SC_POLL			_SC_POLL
+    _SC_SELECT			= 59,
+#define	_SC_SELECT			_SC_SELECT
+    _SC_UIO_MAXIOV		= 60,
+#define	_SC_UIO_MAXIOV			_SC_UIO_MAXIOV
+    _SC_PII_INTERNET_STREAM	= 61,
+#define	_SC_PII_INTERNET_STREAM		_SC_PII_INTERNET_STREAM
+    _SC_PII_INTERNET_DGRAM	= 62,
+#define	_SC_PII_INTERNET_DGRAM		_SC_PII_INTERNET_DGRAM
+    _SC_PII_OSI_COTS		= 63,
+#define	_SC_PII_OSI_COTS		_SC_PII_OSI_COTS
+    _SC_PII_OSI_CLTS		= 64,
+#define	_SC_PII_OSI_CLTS		_SC_PII_OSI_CLTS
+    _SC_PII_OSI_M		= 65,
+#define	_SC_PII_OSI_M			_SC_PII_OSI_M
+    _SC_T_IOV_MAX		= 66,
+#define	_SC_T_IOV_MAX			_SC_T_IOV_MAX
+
+    /* Values according to POSIX 1003.1c (POSIX threads).  */
+    _SC_THREADS			= 67,
+#define	_SC_THREADS			_SC_THREADS
+    _SC_THREAD_SAFE_FUNCTIONS	= 68,
+#define _SC_THREAD_SAFE_FUNCTIONS	_SC_THREAD_SAFE_FUNCTIONS
+    _SC_GETGR_R_SIZE_MAX	= 69,
+#define	_SC_GETGR_R_SIZE_MAX		_SC_GETGR_R_SIZE_MAX
+    _SC_GETPW_R_SIZE_MAX	= 70,
+#define	_SC_GETPW_R_SIZE_MAX		_SC_GETPW_R_SIZE_MAX
+    _SC_LOGIN_NAME_MAX		= 71,
+#define	_SC_LOGIN_NAME_MAX		_SC_LOGIN_NAME_MAX
+    _SC_TTY_NAME_MAX		= 72,
+#define	_SC_TTY_NAME_MAX		_SC_TTY_NAME_MAX
+    _SC_THREAD_DESTRUCTOR_ITERATIONS		= 73,
+#define	_SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS
+    _SC_THREAD_KEYS_MAX		= 74,
+#define	_SC_THREAD_KEYS_MAX		_SC_THREAD_KEYS_MAX
+    _SC_THREAD_STACK_MIN	= 75,
+#define	_SC_THREAD_STACK_MIN		_SC_THREAD_STACK_MIN
+    _SC_THREAD_THREADS_MAX	= 76,
+#define	_SC_THREAD_THREADS_MAX		_SC_THREAD_THREADS_MAX
+    _SC_THREAD_ATTR_STACKADDR	= 77,
+#define	_SC_THREAD_ATTR_STACKADDR	_SC_THREAD_ATTR_STACKADDR
+    _SC_THREAD_ATTR_STACKSIZE	= 78,
+#define	_SC_THREAD_ATTR_STACKSIZE	_SC_THREAD_ATTR_STACKSIZE
+    _SC_THREAD_PRIORITY_SCHEDULING = 79,
+#define	_SC_THREAD_PRIORITY_SCHEDULING	_SC_THREAD_PRIORITY_SCHEDULING
+    _SC_THREAD_PRIO_INHERIT	= 80,
+#define	_SC_THREAD_PRIO_INHERIT		_SC_THREAD_PRIO_INHERIT
+    _SC_THREAD_PRIO_PROTECT	= 81,
+#define	_SC_THREAD_PRIO_PROTECT		_SC_THREAD_PRIO_PROTECT
+    _SC_THREAD_PROCESS_SHARED	= 82,
+#define	_SC_THREAD_PROCESS_SHARED	_SC_THREAD_PROCESS_SHARED
+
+    _SC_NPROCESSORS_CONF	= 83,
+#define _SC_NPROCESSORS_CONF		_SC_NPROCESSORS_CONF
+    _SC_NPROCESSORS_ONLN	= 84,
+#define _SC_NPROCESSORS_ONLN		_SC_NPROCESSORS_ONLN
+    _SC_PHYS_PAGES		= 85,
+#define _SC_PHYS_PAGES			_SC_PHYS_PAGES
+    _SC_AVPHYS_PAGES		= 86,
+#define _SC_AVPHYS_PAGES		_SC_AVPHYS_PAGES
+    _SC_ATEXIT_MAX		= 87,
+#define _SC_ATEXIT_MAX			_SC_ATEXIT_MAX
+    _SC_PASS_MAX		= 88,
+#define _SC_PASS_MAX			_SC_PASS_MAX
+
+    _SC_XOPEN_VERSION		= 89,
+#define _SC_XOPEN_VERSION		_SC_XOPEN_VERSION
+    _SC_XOPEN_XCU_VERSION	= 90,
+#define _SC_XOPEN_XCU_VERSION		_SC_XOPEN_XCU_VERSION
+    _SC_XOPEN_UNIX		= 91,
+#define _SC_XOPEN_UNIX			_SC_XOPEN_UNIX
+    _SC_XOPEN_CRYPT		= 92,
+#define _SC_XOPEN_CRYPT			_SC_XOPEN_CRYPT
+    _SC_XOPEN_ENH_I18N		= 93,
+#define _SC_XOPEN_ENH_I18N		_SC_XOPEN_ENH_I18N
+    _SC_XOPEN_SHM		= 94,
+#define _SC_XOPEN_SHM			_SC_XOPEN_SHM
+
+    _SC_2_CHAR_TERM		= 95,
+#define _SC_2_CHAR_TERM			_SC_2_CHAR_TERM
+    _SC_2_C_VERSION		= 96,
+#define _SC_2_C_VERSION			_SC_2_C_VERSION
+    _SC_2_UPE			= 97,
+#define _SC_2_UPE			_SC_2_UPE
+
+    _SC_XOPEN_XPG2		= 98,
+#define _SC_XOPEN_XPG2			_SC_XOPEN_XPG2
+    _SC_XOPEN_XPG3		= 99,
+#define _SC_XOPEN_XPG3			_SC_XOPEN_XPG3
+    _SC_XOPEN_XPG4		= 100,
+#define _SC_XOPEN_XPG4			_SC_XOPEN_XPG4
+
+    _SC_CHAR_BIT		= 101,
+#define	_SC_CHAR_BIT			_SC_CHAR_BIT
+    _SC_CHAR_MAX		= 102,
+#define	_SC_CHAR_MAX			_SC_CHAR_MAX
+    _SC_CHAR_MIN		= 103,
+#define	_SC_CHAR_MIN			_SC_CHAR_MIN
+    _SC_INT_MAX			= 104,
+#define	_SC_INT_MAX			_SC_INT_MAX
+    _SC_INT_MIN			= 105,
+#define	_SC_INT_MIN			_SC_INT_MIN
+    _SC_LONG_BIT		= 106,
+#define	_SC_LONG_BIT			_SC_LONG_BIT
+    _SC_WORD_BIT		= 107,
+#define	_SC_WORD_BIT			_SC_WORD_BIT
+    _SC_MB_LEN_MAX		= 108,
+#define	_SC_MB_LEN_MAX			_SC_MB_LEN_MAX
+    _SC_NZERO			= 109,
+#define	_SC_NZERO			_SC_NZERO
+    _SC_SSIZE_MAX		= 110,
+#define	_SC_SSIZE_MAX			_SC_SSIZE_MAX
+    _SC_SCHAR_MAX		= 111,
+#define	_SC_SCHAR_MAX			_SC_SCHAR_MAX
+    _SC_SCHAR_MIN		= 112,
+#define	_SC_SCHAR_MIN			_SC_SCHAR_MIN
+    _SC_SHRT_MAX		= 113,
+#define	_SC_SHRT_MAX			_SC_SHRT_MAX
+    _SC_SHRT_MIN		= 114,
+#define	_SC_SHRT_MIN			_SC_SHRT_MIN
+    _SC_UCHAR_MAX		= 115,
+#define	_SC_UCHAR_MAX			_SC_UCHAR_MAX
+    _SC_UINT_MAX		= 116,
+#define	_SC_UINT_MAX			_SC_UINT_MAX
+    _SC_ULONG_MAX		= 117,
+#define	_SC_ULONG_MAX			_SC_ULONG_MAX
+    _SC_USHRT_MAX		= 118,
+#define	_SC_USHRT_MAX			_SC_USHRT_MAX
+
+    _SC_NL_ARGMAX		= 119,
+#define	_SC_NL_ARGMAX			_SC_NL_ARGMAX
+    _SC_NL_LANGMAX		= 120,
+#define	_SC_NL_LANGMAX			_SC_NL_LANGMAX
+    _SC_NL_MSGMAX		= 121,
+#define	_SC_NL_MSGMAX			_SC_NL_MSGMAX
+    _SC_NL_NMAX			= 122,
+#define	_SC_NL_NMAX			_SC_NL_NMAX
+    _SC_NL_SETMAX		= 123,
+#define	_SC_NL_SETMAX			_SC_NL_SETMAX
+    _SC_NL_TEXTMAX		= 124,
+#define	_SC_NL_TEXTMAX			_SC_NL_TEXTMAX
+
+    _SC_XBS5_ILP32_OFF32	= 125,
+#define _SC_XBS5_ILP32_OFF32		_SC_XBS5_ILP32_OFF32
+    _SC_XBS5_ILP32_OFFBIG	= 126,
+#define _SC_XBS5_ILP32_OFFBIG		_SC_XBS5_ILP32_OFFBIG
+    _SC_XBS5_LP64_OFF64		= 127,
+#define _SC_XBS5_LP64_OFF64		_SC_XBS5_LP64_OFF64
+    _SC_XBS5_LPBIG_OFFBIG	= 128,
+#define _SC_XBS5_LPBIG_OFFBIG		_SC_XBS5_LPBIG_OFFBIG
+
+    _SC_XOPEN_LEGACY		= 129,
+#define _SC_XOPEN_LEGACY		_SC_XOPEN_LEGACY
+    _SC_XOPEN_REALTIME		= 130,
+#define _SC_XOPEN_REALTIME		_SC_XOPEN_REALTIME
+    _SC_XOPEN_REALTIME_THREADS	= 131,
+#define _SC_XOPEN_REALTIME_THREADS	_SC_XOPEN_REALTIME_THREADS
+  };
+#endif
+
 #endif /* _LINUX_UNISTD_H_ */
diff -ur linux-23027p1/kernel/sys.c linux-23027p1m1/kernel/sys.c
--- linux-23027p1/kernel/sys.c	Fri Oct 29 23:19:49 1999
+++ linux-23027p1m1/kernel/sys.c	Mon Nov  8 22:58:52 1999
@@ -1034,3 +1138,70 @@
 	return error;
 }
 
+
+/*
+ * POSIX sysconf() things
+ *
+ * There are things for which the existence of this makes
+ * a lot of sense; Adding new facilities to the system allows
+ * things like libc to detect availability of those way easier
+ * thru  sysconf(),  than by any other means.
+ * Mostly these are for other than POSIX.1 things, e.g. for
+ * POSIX.1b, POSIX.1b (aka REAL TIME and THREADS, respectively)
+ *
+ * sysconf() returns -1 for all those option values it does
+ * not recognize.  *Never* shall it set errno!
+ *
+ * Returning ``-1'' without errno is indicated by returning ``-INT_MAX''
+ */
+
+asmlinkage long sys_sysconf(int option)
+{
+	switch(option) {
+#if 0 /* Drepper thinking: These shouldn't be in kernel */
+	case _SC_JOB_CONTROL:		/* POSIX.1 */
+		return 1;
+	case _SC_SAVED_IDS:
+		return -INT_MAX; /* FIXME! What the value *should* be ? */
+	case _SC_VERSION:
+		return -INT_MAX; /* FIXME! What _POSIX_VERSION we have
+				   in the kernel proper ? */
+#endif
+	case _SC_ARG_MAX:
+		return ARG_MAX;
+
+	case _SC_CHILD_MAX:
+		return -INT_MAX;
+
+	case _SC_CLK_TCK:
+		return HZ;
+
+	case _SC_NGROUPS_MAX:
+		return NGROUPS_MAX;
+
+	case _SC_OPEN_MAX:	/* POSIX.1  Max simultaneous files   */
+	case _SC_STREAM_MAX:	/* POSIX.1: Max simultaneous streams */
+		return NR_OPEN; /* The upper hard limit; Normally something
+				   like 1024, but insanely large file arrays
+				   can also be supported in the system giving
+				   this here 1024*1024 (yep, MILLION!) */
+
+#if 0	/* Library thing */
+	case _SC_TZNAME_MAX:
+		return -INT_MAX;
+#endif
+#if 0 /* Drepper thinking: Most of these are library things, and don't
+	 belong to kernel..  Must sort them out someday.. */
+	case _SC_ASYNCHRONOUS_IO:	/* POSIX.4 */
+	case _SC_MAPPED_FILES:
+	case _SC_MEMLOCK:
+	case _SC_MEMLOCK_RANGE:
+	case _SC_MEMORY_PROTECTION:
+		/* ... more! ... */
+		break;
+#endif
+	default:	/* Anything not considered in kernel -> EINVAL */
+		break;
+	}
+	return -EINVAL;
+}
diff -ur linux-23027p1/kernel/sys.c linux-23027p1m1/kernel/sys.c
--- linux-23027p1/kernel/sys.c	Fri Oct 29 23:19:49 1999
+++ linux-23027p1m1/kernel/sys.c	Mon Nov  8 22:58:52 1999
@@ -1034,3 +1138,70 @@
 	return error;
 }
 
+
+/*
+ * POSIX sysconf() things
+ *
+ * There are things for which the existence of this makes
+ * a lot of sense; Adding new facilities to the system allows
+ * things like libc to detect availability of those way easier
+ * thru  sysconf(),  than by any other means.
+ * Mostly these are for other than POSIX.1 things, e.g. for
+ * POSIX.1b, POSIX.1b (aka REAL TIME and THREADS, respectively)
+ *
+ * sysconf() returns -1 for all those option values it does
+ * not recognize.  *Never* shall it set errno!
+ *
+ * Returning ``-1'' without errno is indicated by returning ``-INT_MAX''
+ */
+
+asmlinkage long sys_sysconf(int option)
+{
+	switch(option) {
+#if 0 /* Drepper thinking: These shouldn't be in kernel */
+	case _SC_JOB_CONTROL:		/* POSIX.1 */
+		return 1;
+	case _SC_SAVED_IDS:
+		return -INT_MAX; /* FIXME! What the value *should* be ? */
+	case _SC_VERSION:
+		return -INT_MAX; /* FIXME! What _POSIX_VERSION we have
+				   in the kernel proper ? */
+#endif
+	case _SC_ARG_MAX:
+		return ARG_MAX;
+
+	case _SC_CHILD_MAX:
+		return -INT_MAX;
+
+	case _SC_CLK_TCK:
+		return HZ;
+
+	case _SC_NGROUPS_MAX:
+		return NGROUPS_MAX;
+
+	case _SC_OPEN_MAX:	/* POSIX.1  Max simultaneous files   */
+	case _SC_STREAM_MAX:	/* POSIX.1: Max simultaneous streams */
+		return NR_OPEN; /* The upper hard limit; Normally something
+				   like 1024, but insanely large file arrays
+				   can also be supported in the system giving
+				   this here 1024*1024 (yep, MILLION!) */
+
+#if 0	/* Library thing */
+	case _SC_TZNAME_MAX:
+		return -INT_MAX;
+#endif
+#if 0 /* Drepper thinking: Most of these are library things, and don't
+	 belong to kernel..  Must sort them out someday.. */
+	case _SC_ASYNCHRONOUS_IO:	/* POSIX.4 */
+	case _SC_MAPPED_FILES:
+	case _SC_MEMLOCK:
+	case _SC_MEMLOCK_RANGE:
+	case _SC_MEMORY_PROTECTION:
+		/* ... more! ... */
+		break;
+#endif
+	default:	/* Anything not considered in kernel -> EINVAL */
+		break;
+	}
+	return -EINVAL;
+}
diff -ur linux-23027p1/include/linux/stat.h linux-23027p1m1/include/linux/stat.h
--- linux-23027p1/include/linux/stat.h	Mon May 25 20:32:52 1998
+++ linux-23027p1m1/include/linux/stat.h	Mon Nov  8 22:58:52 1999
@@ -3,8 +3,43 @@
 
 #ifdef __KERNEL__
 
+#include <linux/types.h>
 #include <asm/stat.h>
 
+#ifndef __ARCH_STRUCT_STAT64
+
+struct stat64 { /* Generically sized structure for all Linuxes */
+	__u64	st_dev;		/* Usually 16 or 32 bits */
+	__u64	st_rdev;
+
+	__u32	st_mode;
+	__u32	st_nlink;
+
+	__u32	st_uid;
+	__u32	st_gid;
+
+	__u64	st_ino;		/* inode is usually mere 32-bits */
+
+	__s64	st_size;	/* Large File Support */
+	__s64	st_blocks;
+	__u32	st_blksize;
+	__u32   __unused0;
+
+	long	st_atime;	/* Yup, 32 bits or 64 bits per natural */
+	long	__unused1;	/* .. size of the 'long'. */
+	long	st_mtime;
+	long	__unused2;
+	long	st_ctime;
+	long	__unused3;
+
+	__u64	st_gen;		/* Linux-FS things */
+	__u64	st_flags;
+
+	char	st_fstype[16];	/* Filesystem type name; From SysV */
+
+	__u32	__unused4[32];	/* some reserved space for possible extensions */
+};
+#endif
 #endif
 
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
