diff -ruN linux-2.3.12-vanilla/fs/exec.c linux-2.3.12-fist/fs/exec.c
--- linux-2.3.12-vanilla/fs/exec.c	Tue Jul 27 17:53:14 1999
+++ linux-2.3.12-fist/fs/exec.c	Thu Jul 29 16:12:03 1999
@@ -306,7 +306,7 @@
 		mpnt->vm_ops = NULL;
 		mpnt->vm_offset = 0;
 		mpnt->vm_file = NULL;
-		mpnt->vm_pte = 0;
+		mpnt->vm_private_data = (void *) 0;
 		insert_vm_struct(current->mm, mpnt);
 		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 	} 
diff -ruN linux-2.3.12-vanilla/fs/namei.c linux-2.3.12-fist/fs/namei.c
--- linux-2.3.12-vanilla/fs/namei.c	Mon Jul  5 23:34:31 1999
+++ linux-2.3.12-fist/fs/namei.c	Thu Jul 29 16:12:03 1999
@@ -16,6 +16,7 @@
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/quotaops.h>
+#include <linux/dcache_func.h>
 
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
@@ -537,83 +538,6 @@
 		return -EEXIST;
 	return permission(dir,MAY_WRITE | MAY_EXEC);
 }
-
-static inline struct dentry *get_parent(struct dentry *dentry)
-{
-	return dget(dentry->d_parent);
-}
-
-static inline void unlock_dir(struct dentry *dir)
-{
-	up(&dir->d_inode->i_sem);
-	dput(dir);
-}
-
-/*
- * We need to do a check-parent every time
- * after we have locked the parent - to verify
- * that the parent is still our parent and
- * that we are still hashed onto it..
- *
- * This is requied in case two processes race
- * on removing (or moving) the same entry: the
- * parent lock will serialize them, but the
- * other process will be too late..
- */
-#define check_parent(dir, dentry) \
-	((dir) == (dentry)->d_parent && !list_empty(&dentry->d_hash))
-
-/*
- * Locking the parent is needed to:
- *  - serialize directory operations
- *  - make sure the parent doesn't change from
- *    under us in the middle of an operation.
- *
- * NOTE! Right now we'd rather use a "struct inode"
- * for this, but as I expect things to move toward
- * using dentries instead for most things it is
- * probably better to start with the conceptually
- * better interface of relying on a path of dentries.
- */
-static inline struct dentry *lock_parent(struct dentry *dentry)
-{
-	struct dentry *dir = dget(dentry->d_parent);
-
-	down(&dir->d_inode->i_sem);
-	return dir;
-}
-
-/*
- * Whee.. Deadlock country. Happily there are only two VFS
- * operations that do this..
- */
-static inline void double_lock(struct dentry *d1, struct dentry *d2)
-{
-	struct semaphore *s1 = &d1->d_inode->i_sem;
-	struct semaphore *s2 = &d2->d_inode->i_sem;
-
-	if (s1 != s2) {
-		if ((unsigned long) s1 < (unsigned long) s2) {
-			struct semaphore *tmp = s2;
-			s2 = s1; s1 = tmp;
-		}
-		down(s1);
-	}
-	down(s2);
-}
-
-static inline void double_unlock(struct dentry *d1, struct dentry *d2)
-{
-	struct semaphore *s1 = &d1->d_inode->i_sem;
-	struct semaphore *s2 = &d2->d_inode->i_sem;
-
-	up(s1);
-	if (s1 != s2)
-		up(s2);
-	dput(d1);
-	dput(d2);
-}
-
 
 /* 
  * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
diff -ruN linux-2.3.12-vanilla/fs/nfsd/vfs.c linux-2.3.12-fist/fs/nfsd/vfs.c
--- linux-2.3.12-vanilla/fs/nfsd/vfs.c	Mon Jul  5 23:34:31 1999
+++ linux-2.3.12-fist/fs/nfsd/vfs.c	Thu Jul 29 16:12:03 1999
@@ -995,12 +995,15 @@
  * that the parent is still our parent and
  * that we are still hashed onto it..
  *
- * This is requied in case two processes race
+ * This is required in case two processes race
  * on removing (or moving) the same entry: the
  * parent lock will serialize them, but the
  * other process will be too late..
+ *
+ * Note that this nfsd_check_parent is different
+ * than the one in linux/include/dcache_func.h.
  */
-#define check_parent(dir, dentry) \
+#define nfsd_check_parent(dir, dentry) \
 	((dir) == (dentry)->d_parent->d_inode && !list_empty(&dentry->d_hash))
 
 /*
@@ -1079,8 +1082,8 @@
 	nfsd_double_down(&tdir->i_sem, &fdir->i_sem);
 	err = -ENOENT;
 	/* GAM3 check for parent changes after locking. */
-	if (check_parent(fdir, odentry) &&
-	    check_parent(tdir, ndentry)) {
+	if (nfsd_check_parent(fdir, odentry) &&
+	    nfsd_check_parent(tdir, ndentry)) {
 
 		err = vfs_rename(fdir, odentry, tdir, ndentry);
 		if (!err && EX_ISSYNC(tfhp->fh_export)) {
@@ -1168,7 +1171,7 @@
 		fhp->fh_locked = 1;
 
 		err = -ENOENT;
-		if (check_parent(dirp, rdentry))
+		if (nfsd_check_parent(dirp, rdentry))
 			err = vfs_rmdir(dirp, rdentry);
 
 		rdentry->d_count--;
diff -ruN linux-2.3.12-vanilla/fs/read_write.c linux-2.3.12-fist/fs/read_write.c
--- linux-2.3.12-vanilla/fs/read_write.c	Mon Jun 28 16:31:07 1999
+++ linux-2.3.12-fist/fs/read_write.c	Thu Jul 29 16:12:03 1999
@@ -13,7 +13,7 @@
 
 #include <asm/uaccess.h>
 
-static loff_t default_llseek(struct file *file, loff_t offset, int origin)
+loff_t default_llseek(struct file *file, loff_t offset, int origin)
 {
 	long long retval;
 
diff -ruN linux-2.3.12-vanilla/include/linux/dcache_func.h linux-2.3.12-fist/include/linux/dcache_func.h
--- linux-2.3.12-vanilla/include/linux/dcache_func.h	Wed Dec 31 19:00:00 1969
+++ linux-2.3.12-fist/include/linux/dcache_func.h	Thu Jul 29 16:12:03 1999
@@ -0,0 +1,91 @@
+#ifndef __LINUX_DCACHE_FUNC_H
+#define __LINUX_DCACHE_FUNC_H
+
+/*
+ * Common dentry functions for inclusion in the VFS
+ * or in other stackable file systems.  Some of these
+ * functions were in linux/fs/ C (VFS) files.
+ */
+#ifdef __KERNEL__
+#include <linux/dcache.h>
+#include <asm/semaphore.h>
+
+/*
+ * We need to do a check-parent every time
+ * after we have locked the parent - to verify
+ * that the parent is still our parent and
+ * that we are still hashed onto it..
+ *
+ * This is required in case two processes race
+ * on removing (or moving) the same entry: the
+ * parent lock will serialize them, but the
+ * other process will be too late..
+ */
+#define check_parent(dir, dentry) \
+	((dir) == (dentry)->d_parent && !list_empty(&dentry->d_hash))
+
+/*
+ * Locking the parent is needed to:
+ *  - serialize directory operations
+ *  - make sure the parent doesn't change from
+ *    under us in the middle of an operation.
+ *
+ * NOTE! Right now we'd rather use a "struct inode"
+ * for this, but as I expect things to move toward
+ * using dentries instead for most things it is
+ * probably better to start with the conceptually
+ * better interface of relying on a path of dentries.
+ */
+static inline struct dentry *lock_parent(struct dentry *dentry)
+{
+	struct dentry *dir = dget(dentry->d_parent);
+
+	down(&dir->d_inode->i_sem);
+	return dir;
+}
+
+static inline struct dentry *get_parent(struct dentry *dentry)
+{
+	return dget(dentry->d_parent);
+}
+
+static inline void unlock_dir(struct dentry *dir)
+{
+	up(&dir->d_inode->i_sem);
+	dput(dir);
+}
+
+/*
+ * Whee.. Deadlock country. Happily there is only one VFS
+ * operation that does this..
+ */
+static inline void double_lock(struct dentry *d1, struct dentry *d2)
+{
+	struct semaphore *s1 = &d1->d_inode->i_sem;
+	struct semaphore *s2 = &d2->d_inode->i_sem;
+
+	if (s1 != s2) {
+		if ((unsigned long) s1 < (unsigned long) s2) {
+			struct semaphore *tmp = s2;
+			s2 = s1; s1 = tmp;
+		}
+		down(s1);
+	}
+	down(s2);
+}
+
+static inline void double_unlock(struct dentry *d1, struct dentry *d2)
+{
+	struct semaphore *s1 = &d1->d_inode->i_sem;
+	struct semaphore *s2 = &d2->d_inode->i_sem;
+
+	up(s1);
+	if (s1 != s2)
+		up(s2);
+	dput(d1);
+	dput(d2);
+}
+
+#endif /* __KERNEL__ */
+
+#endif	/* __LINUX_DCACHE_FUNC_H */
diff -ruN linux-2.3.12-vanilla/include/linux/fs.h linux-2.3.12-fist/include/linux/fs.h
--- linux-2.3.12-vanilla/include/linux/fs.h	Wed Jul 28 16:56:34 1999
+++ linux-2.3.12-fist/include/linux/fs.h	Thu Jul 29 20:42:33 1999
@@ -903,6 +903,7 @@
 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
 extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
 extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *, writepage_t);
+extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
 
 
 extern struct super_block *get_super(kdev_t);
diff -ruN linux-2.3.12-vanilla/include/linux/mm.h linux-2.3.12-fist/include/linux/mm.h
--- linux-2.3.12-vanilla/include/linux/mm.h	Wed Jul 28 16:56:38 1999
+++ linux-2.3.12-fist/include/linux/mm.h	Thu Jul 29 20:42:34 1999
@@ -56,7 +56,7 @@
 	struct vm_operations_struct * vm_ops;
 	unsigned long vm_offset;
 	struct file * vm_file;
-	unsigned long vm_pte;			/* shared mem */
+	void * vm_private_data;		/* was vm_pte (shared mem) */
 };
 
 /*
@@ -348,6 +348,14 @@
 extern void truncate_inode_pages(struct inode *, unsigned long);
 extern unsigned long get_cached_page(struct inode *, unsigned long, int);
 extern void put_cached_page(unsigned long);
+/* generic vm_area_ops exported for stackable file systems */
+extern int filemap_swapout(struct vm_area_struct * vma, struct page * page);
+extern pte_t filemap_swapin(struct vm_area_struct * vma,
+			    unsigned long offset, unsigned long entry);
+extern int filemap_sync(struct vm_area_struct * vma, unsigned long address,
+			size_t size, unsigned int flags);
+extern unsigned long filemap_nopage(struct vm_area_struct * area,
+				    unsigned long address, int no_share);
 
 /*
  * GFP bitmasks..
diff -ruN linux-2.3.12-vanilla/ipc/shm.c linux-2.3.12-fist/ipc/shm.c
--- linux-2.3.12-vanilla/ipc/shm.c	Tue Jul 13 12:25:59 1999
+++ linux-2.3.12-fist/ipc/shm.c	Thu Jul 29 16:12:03 1999
@@ -370,7 +370,7 @@
  * shmd->vm_next	next attach for task
  * shmd->vm_next_share	next attach for segment
  * shmd->vm_offset	offset into segment
- * shmd->vm_pte		signature for this attach
+ * shmd->vm_private_data		signature for this attach
  */
 
 static struct vm_operations_struct shm_vm_ops = {
@@ -509,7 +509,7 @@
 		goto out;
 	}
 
-	shmd->vm_pte = SWP_ENTRY(SHM_SWP_TYPE, id);
+	shmd->vm_private_data = (void *) SWP_ENTRY(SHM_SWP_TYPE, id);
 	shmd->vm_start = addr;
 	shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
 	shmd->vm_mm = current->mm;
@@ -549,7 +549,7 @@
 	struct shmid_kernel *shp;
 
 	lock_kernel();
-	id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
+	id = SWP_OFFSET((unsigned long) shmd->vm_private_data) & SHM_ID_MASK;
 	shp = shm_segs[id];
 	if (shp == IPC_UNUSED) {
 		printk("shm_open: unused id=%d PANIC\n", id);
@@ -575,7 +575,7 @@
 
 	lock_kernel();
 	/* remove from the list of attaches of the shm segment */
-	id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
+	id = SWP_OFFSET((unsigned long) shmd->vm_private_data) & SHM_ID_MASK;
 	shp = shm_segs[id];
 	remove_attach(shp,shmd);  /* remove from shp->attaches */
   	shp->u.shm_lpid = current->pid;
@@ -630,7 +630,7 @@
 	unsigned long page;
 	struct page * page_map;
 
-	id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
+	id = SWP_OFFSET((unsigned long) shmd->vm_private_data) & SHM_ID_MASK;
 	idx = (address - shmd->vm_start + shmd->vm_offset) >> PAGE_SHIFT;
 
 #ifdef DEBUG_SHM
diff -ruN linux-2.3.12-vanilla/kernel/ksyms.c linux-2.3.12-fist/kernel/ksyms.c
--- linux-2.3.12-vanilla/kernel/ksyms.c	Mon Jul 19 15:31:25 1999
+++ linux-2.3.12-fist/kernel/ksyms.c	Thu Jul 29 16:48:01 1999
@@ -195,7 +195,17 @@
 EXPORT_SYMBOL(add_to_page_cache_unique);
 EXPORT_SYMBOL(__find_get_page);
 EXPORT_SYMBOL(__find_lock_page);
-                        
+
+/* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
+EXPORT_SYMBOL(___wait_on_page);
+EXPORT_SYMBOL(add_to_page_cache);
+EXPORT_SYMBOL(default_llseek);
+EXPORT_SYMBOL(filemap_nopage);
+EXPORT_SYMBOL(filemap_swapout);
+EXPORT_SYMBOL(filemap_sync);
+EXPORT_SYMBOL(remove_inode_page);
+EXPORT_SYMBOL(swap_free);
+
 #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
 EXPORT_SYMBOL(do_nfsservctl);
 #endif
diff -ruN linux-2.3.12-vanilla/mm/filemap.c linux-2.3.12-fist/mm/filemap.c
--- linux-2.3.12-vanilla/mm/filemap.c	Mon Jul 12 10:49:36 1999
+++ linux-2.3.12-fist/mm/filemap.c	Thu Jul 29 16:12:04 1999
@@ -1278,7 +1278,7 @@
  * WSH 06/04/97: fixed a memory leak and moved the allocation of new_page
  * ahead of the wait if we're sure to need it.
  */
-static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
+unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
 {
 	struct file * file = area->vm_file;
 	struct dentry * dentry = file->f_dentry;
@@ -1596,7 +1596,7 @@
 	return error;
 }
 
-static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
+int filemap_sync(struct vm_area_struct * vma, unsigned long address,
 	size_t size, unsigned int flags)
 {
 	pgd_t * dir;
diff -ruN linux-2.3.12-vanilla/mm/mmap.c linux-2.3.12-fist/mm/mmap.c
--- linux-2.3.12-vanilla/mm/mmap.c	Tue Jul 27 15:33:27 1999
+++ linux-2.3.12-fist/mm/mmap.c	Thu Jul 29 16:12:04 1999
@@ -275,7 +275,7 @@
 	vma->vm_ops = NULL;
 	vma->vm_offset = off;
 	vma->vm_file = NULL;
-	vma->vm_pte = 0;
+	vma->vm_private_data = (void *) 0;
 
 	/* Clear old maps */
 	error = -ENOMEM;
@@ -547,7 +547,7 @@
 		mpnt->vm_ops = area->vm_ops;
 		mpnt->vm_offset = area->vm_offset + (end - area->vm_start);
 		mpnt->vm_file = area->vm_file;
-		mpnt->vm_pte = area->vm_pte;
+		mpnt->vm_private_data = area->vm_private_data;
 		if (mpnt->vm_file)
 			get_file(mpnt->vm_file);
 		if (mpnt->vm_ops && mpnt->vm_ops->open)
@@ -778,7 +778,7 @@
 	vma->vm_ops = NULL;
 	vma->vm_offset = 0;
 	vma->vm_file = NULL;
-	vma->vm_pte = 0;
+	vma->vm_private_data = (void *) 0;
 
 	/*
 	 * merge_segments may merge our vma, so we can't refer to it
@@ -920,7 +920,7 @@
 
 		/* To share, we must have the same file, operations.. */
 		if ((mpnt->vm_file != prev->vm_file)||
-		    (mpnt->vm_pte != prev->vm_pte)	||
+		    (mpnt->vm_private_data != prev->vm_private_data)	||
 		    (mpnt->vm_ops != prev->vm_ops)	||
 		    (mpnt->vm_flags != prev->vm_flags)	||
 		    (prev->vm_end != mpnt->vm_start))
