diff -u --recursive --new-file v1.1.35/linux/Makefile linux/Makefile
--- v1.1.35/linux/Makefile	Mon Jul 25 17:56:37 1994
+++ linux/Makefile	Mon Jul 25 22:03:50 1994
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 35
+SUBLEVEL = 36
 
 all:	Version zImage
 
diff -u --recursive --new-file v1.1.35/linux/drivers/char/console.c linux/drivers/char/console.c
--- v1.1.35/linux/drivers/char/console.c	Mon Jul 25 17:56:37 1994
+++ linux/drivers/char/console.c	Tue Jul 26 08:30:54 1994
@@ -629,6 +629,27 @@
 	need_wrap = 0;
 }
 
+static void csi_X(int currcons, int vpar)
+{
+	long count;
+	long start;
+
+	if (!vpar)
+	        vpar++;
+
+	start=pos;
+	count=(vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
+
+	__asm__("cld\n\t"
+		"rep\n\t"
+		"stosw\n\t"
+		: /* no output */
+		:"c" (count),
+		"D" (start),"a" (video_erase_char)
+		:"cx","di");
+	need_wrap = 0;
+}
+
 /*
  *  I hope this works. The monochrome part is untested.
  */
@@ -1346,6 +1367,9 @@
 						continue;
 					case 'u':
 						restore_cur(currcons);
+						continue;
+					case 'X':
+						csi_X(currcons, par[0]);
 						continue;
 					case '@':
 						csi_at(currcons,par[0]);
diff -u --recursive --new-file v1.1.35/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v1.1.35/linux/drivers/char/mem.c	Mon Jul 25 17:56:37 1994
+++ linux/drivers/char/mem.c	Mon Jul 25 11:49:28 1994
@@ -83,34 +83,18 @@
 	return count;
 }
 
-static int mmap_mem(struct inode * inode, struct file * file,
-	unsigned long addr, size_t len, int prot, unsigned long off)
+static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_struct * vma)
 {
-	struct vm_area_struct * mpnt;
-
-	if (off & 0xfff || off + len < off)
+	if (vma->vm_offset & ~PAGE_MASK)
 		return -ENXIO;
-	if (x86 > 3 && off >= high_memory)
-		prot |= PAGE_PCD;
-	if (remap_page_range(addr, off, len, prot))
+	if (x86 > 3 && vma->vm_offset >= high_memory)
+		vma->vm_page_prot |= PAGE_PCD;
+	if (remap_page_range(vma->vm_start, vma->vm_offset, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
-/* try to create a dummy vmm-structure so that the rest of the kernel knows we are here */
-	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
-	if (!mpnt)
-		return 0;
-
-	mpnt->vm_task = current;
-	mpnt->vm_start = addr;
-	mpnt->vm_end = addr + len;
-	mpnt->vm_page_prot = prot;
-	mpnt->vm_flags = 0;
-	mpnt->vm_share = NULL;
-	mpnt->vm_inode = inode;
+	vma->vm_inode = inode;
 	inode->i_count++;
-	mpnt->vm_offset = off;
-	mpnt->vm_ops = NULL;
-	insert_vm_struct(current, mpnt);
-	merge_segments(current->mm->mmap, NULL, NULL);
+	insert_vm_struct(current, vma);
+	merge_segments(current->mm->mmap);
 	return 0;
 }
 
@@ -177,34 +161,14 @@
 	return count;
 }
 
-static int mmap_zero(struct inode * inode, struct file * file,
-	unsigned long addr, size_t len, int prot, unsigned long off)
+static int mmap_zero(struct inode * inode, struct file * file, struct vm_area_struct * vma)
 {
-	struct vm_area_struct *mpnt;
-
-	if (prot & PAGE_RW)
+	if (vma->vm_page_prot & PAGE_RW)
 		return -EINVAL;
-	if (zeromap_page_range(addr, len, prot))
+	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
-	/*
-	 * try to create a dummy vmm-structure so that the
-	 * rest of the kernel knows we are here
-	 */
-	mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
-	if (!mpnt)
-		return 0;
-
-	mpnt->vm_task = current;
-	mpnt->vm_start = addr;
-	mpnt->vm_end = addr + len;
-	mpnt->vm_page_prot = prot;
-	mpnt->vm_flags = 0;
-	mpnt->vm_share = NULL;
-	mpnt->vm_inode = NULL;
-	mpnt->vm_offset = off;
-	mpnt->vm_ops = NULL;
-	insert_vm_struct(current, mpnt);
-	merge_segments(current->mm->mmap, ignoff_mergep, inode);
+	insert_vm_struct(current, vma);
+	merge_segments(current->mm->mmap);
 	return 0;
 }
 
diff -u --recursive --new-file v1.1.35/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v1.1.35/linux/drivers/net/de600.c	Wed Jun 22 14:57:09 1994
+++ linux/drivers/net/de600.c	Mon Jul 25 12:06:19 1994
@@ -1,5 +1,5 @@
 static char *version =
-	"de600.c: $Revision: 1.39 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
+	"de600.c: $Revision: 1.40 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
 /*
  *	de600.c
  *
@@ -76,8 +76,10 @@
  * Tricks TCP to announce a small max window (max 2 fast packets please :-)
  *
  * Comment away at your own risk!
+ *
+ * Update: Use the more general per-device maxwindow parameter instead.
  */
-#define FAKE_SMALL_MAX
+#undef FAKE_SMALL_MAX
 
 /* use 0 for production, 1 for verification, >2 for debug */
 #ifdef DE600_DEBUG
@@ -106,8 +108,10 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#ifdef MODULE
 #include <linux/module.h>
 #include "../../tools/version.h"
+#endif
 
 #ifdef FAKE_SMALL_MAX
 static unsigned long de600_rspace(struct sock *sk);
diff -u --recursive --new-file v1.1.35/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v1.1.35/linux/drivers/net/de620.c	Wed Jun 22 14:57:09 1994
+++ linux/drivers/net/de620.c	Mon Jul 25 12:04:37 1994
@@ -1,5 +1,5 @@
 /*
- *	de620.c $Revision: 1.30 $ BETA
+ *	de620.c $Revision: 1.31 $ BETA
  *
  *
  *	Linux driver for the D-Link DE-620 Ethernet pocket adapter.
@@ -39,7 +39,7 @@
  *
  *****************************************************************************/
 static char *version =
-	"de620.c: $Revision: 1.30 $,  Bjorn Ekwall <bj0rn@blox.se>\n";
+	"de620.c: $Revision: 1.31 $,  Bjorn Ekwall <bj0rn@blox.se>\n";
 
 /***********************************************************************
  *
@@ -119,8 +119,10 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#ifdef MODULE
 #include <linux/module.h>
 #include "../../tools/version.h"
+#endif
 
 /* Constant definitions for the DE-620 registers, commands and bits */
 #include "de620.h"
diff -u --recursive --new-file v1.1.35/linux/drivers/sound/sb_dsp.c linux/drivers/sound/sb_dsp.c
--- v1.1.35/linux/drivers/sound/sb_dsp.c	Thu Jul 21 08:18:18 1994
+++ linux/drivers/sound/sb_dsp.c	Sun Jul 24 22:49:27 1994
@@ -794,7 +794,7 @@
     mixer_type = sb_mixer_init (sbc_major);
 #endif
 
-#ifndef EXCLUDE_YM8312
+#ifndef EXCLUDE_YM3812
 
   if (sbc_major > 3 ||
       (sbc_major == 3 && INB (0x388) == 0x00))	/* Should be 0x06 if not OPL-3 */
diff -u --recursive --new-file v1.1.35/linux/fs/exec.c linux/fs/exec.c
--- v1.1.35/linux/fs/exec.c	Fri Jul 22 16:41:02 1994
+++ linux/fs/exec.c	Tue Jul 26 11:33:58 1994
@@ -322,11 +322,12 @@
 		mpnt->vm_start = PAGE_MASK & (unsigned long) p;
 		mpnt->vm_end = TASK_SIZE;
 		mpnt->vm_page_prot = PAGE_PRIVATE|PAGE_DIRTY;
-		mpnt->vm_flags = VM_GROWSDOWN;
+		mpnt->vm_flags = VM_STACK_FLAGS;
 		mpnt->vm_share = NULL;
-		mpnt->vm_inode = NULL;
-		mpnt->vm_offset = 0;
 		mpnt->vm_ops = NULL;
+		mpnt->vm_offset = 0;
+		mpnt->vm_inode = NULL;
+		mpnt->vm_pte = 0;
 		insert_vm_struct(current, mpnt);
 	}
 	sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
@@ -525,10 +526,6 @@
 	current->comm[i] = '\0';
 	if (current->shm)
 		shm_exit();
-	if (current->executable) {
-		iput(current->executable);
-		current->executable = NULL;
-	}
 	/* Release all of the old mmap stuff. */
 
 	mpnt = current->mm->mmap;
@@ -821,7 +818,6 @@
 		(current->mm->start_code = N_TXTADDR(ex)))));
 	current->mm->rss = 0;
 	current->mm->mmap = NULL;
-	current->executable = NULL;  /* for OMAGIC files */
 	current->suid = current->euid = bprm->e_uid;
 	current->sgid = current->egid = bprm->e_gid;
 	if (N_MAGIC(ex) == OMAGIC) {
@@ -851,7 +847,8 @@
 		if (ex.a_text) {
 			error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
 				PROT_READ | PROT_EXEC,
-				MAP_FIXED | MAP_SHARED, fd_offset);
+				MAP_FIXED | MAP_SHARED | MAP_DENYWRITE,
+				fd_offset);
 
 			if (error != N_TXTADDR(ex)) {
 				sys_close(fd);
@@ -862,14 +859,13 @@
 		
  		error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
 				PROT_READ | PROT_WRITE | PROT_EXEC,
-				MAP_FIXED | MAP_PRIVATE, fd_offset + ex.a_text);
+				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
+				fd_offset + ex.a_text);
 		sys_close(fd);
 		if (error != N_TXTADDR(ex) + ex.a_text) {
 			send_sig(SIGSEGV, current, 0);
 			return -EINVAL;
 		}
-		current->executable = bprm->inode;
-		bprm->inode->i_count++;
 	}
 beyond_if:
 	if (current->exec_domain && current->exec_domain->use_count)
@@ -939,7 +935,8 @@
 
 	/* Now use mmap to map the library into memory. */
 	error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
-			PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
+			PROT_READ | PROT_WRITE | PROT_EXEC,
+			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
 			N_TXTOFF(ex));
 	if (error != start_addr)
 		return error;
diff -u --recursive --new-file v1.1.35/linux/fs/msdos/mmap.c linux/fs/msdos/mmap.c
--- v1.1.35/linux/fs/msdos/mmap.c	Mon Jul 25 17:56:40 1994
+++ linux/fs/msdos/mmap.c	Mon Jul 25 12:47:38 1994
@@ -81,19 +81,11 @@
  * This is used for a general mmap of an msdos file
  * Returns 0 if ok, or a negative error code if not.
  */
-int msdos_mmap(
-	struct inode * inode,
-	struct file * file,
-	unsigned long addr,
-	size_t len,
-	int prot,
-	unsigned long off)
+int msdos_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
 {
-	struct vm_area_struct * mpnt;
-
-	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported now */
+	if (vma->vm_page_prot & PAGE_RW)	/* only PAGE_COW or read-only supported now */
 		return -EINVAL;
-	if (off & (inode->i_sb->s_blocksize - 1))
+	if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
 		return -EINVAL;
 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
 		return -EACCES;
@@ -102,22 +94,12 @@
 		inode->i_dirt = 1;
 	}
 
-	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
-	if (!mpnt)
-		return -ENOMEM;
-
-	unmap_page_range(addr, len);
-	mpnt->vm_task = current;
-	mpnt->vm_start = addr;
-	mpnt->vm_end = addr + len;
-	mpnt->vm_page_prot = prot;
-	mpnt->vm_share = NULL;
-	mpnt->vm_inode = inode;
+	unmap_page_range(vma->vm_start, vma->vm_end - vma->vm_start);
+	vma->vm_inode = inode;
 	inode->i_count++;
-	mpnt->vm_offset = off;
-	mpnt->vm_ops = &msdos_file_mmap;
-	insert_vm_struct (current,mpnt);
-	merge_segments (current->mm->mmap,NULL,NULL);
+	vma->vm_ops = &msdos_file_mmap;
+	insert_vm_struct(current, vma);
+	merge_segments(current->mm->mmap);
 	return 0;
 }
 
diff -u --recursive --new-file v1.1.35/linux/fs/namei.c linux/fs/namei.c
--- v1.1.35/linux/fs/namei.c	Sat May  7 14:54:08 1994
+++ linux/fs/namei.c	Tue Jul 26 11:30:07 1994
@@ -353,14 +353,12 @@
 		        struct vm_area_struct * mpnt;
  			if (!*p)
  				continue;
- 			if (inode == (*p)->executable) {
- 				iput(inode);
- 				return -ETXTBSY;
- 			}
 			for(mpnt = (*p)->mm->mmap; mpnt; mpnt = mpnt->vm_next) {
+				if (inode != mpnt->vm_inode)
+					continue;
 				if (mpnt->vm_page_prot & PAGE_RW)
 					continue;
-				if (inode == mpnt->vm_inode) {
+				if (mpnt->vm_flags & VM_DENYWRITE) {
 					iput(inode);
 					return -ETXTBSY;
 				}
diff -u --recursive --new-file v1.1.35/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v1.1.35/linux/fs/nfs/file.c	Wed Dec  1 14:44:15 1993
+++ linux/fs/nfs/file.c	Mon Jul 25 12:54:07 1994
@@ -21,8 +21,7 @@
 static int nfs_file_read(struct inode *, struct file *, char *, int);
 static int nfs_file_write(struct inode *, struct file *, char *, int);
 static int nfs_fsync(struct inode *, struct file *);
-extern int nfs_mmap(struct inode * inode, struct file * file,
-	      unsigned long addr, size_t len, int prot, unsigned long off);
+extern int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma);
 
 static struct file_operations nfs_file_operations = {
 	NULL,			/* lseek - default */
diff -u --recursive --new-file v1.1.35/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c
--- v1.1.35/linux/fs/nfs/mmap.c	Sat Jul 23 17:38:37 1994
+++ linux/fs/nfs/mmap.c	Mon Jul 25 12:56:02 1994
@@ -85,14 +85,9 @@
 
 
 /* This is used for a general mmap of a nfs file */
-int nfs_mmap(struct inode * inode, struct file * file,
-	unsigned long addr, size_t len, int prot, unsigned long off)
+int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
 {
-	struct vm_area_struct * mpnt;
-
-	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported now */
-		return -EINVAL;
-	if (off & (inode->i_sb->s_blocksize - 1))
+	if (vma->vm_page_prot & PAGE_RW)	/* only PAGE_COW or read-only supported now */
 		return -EINVAL;
 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
 		return -EACCES;
@@ -101,22 +96,11 @@
 		inode->i_dirt = 1;
 	}
 
-	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
-	if (!mpnt)
-		return -ENOMEM;
-
-	unmap_page_range(addr, len);
-	mpnt->vm_task = current;
-	mpnt->vm_start = addr;
-	mpnt->vm_end = addr + len;
-	mpnt->vm_page_prot = prot;
-	mpnt->vm_flags = 0;
-	mpnt->vm_share = NULL;
-	mpnt->vm_inode = inode;
+	unmap_page_range(vma->vm_start, vma->vm_end - vma->vm_start);
+	vma->vm_inode = inode;
 	inode->i_count++;
-	mpnt->vm_offset = off;
-	mpnt->vm_ops = &nfs_file_mmap;
-	insert_vm_struct(current, mpnt);
-	merge_segments(current->mm->mmap, NULL, NULL);
+	vma->vm_ops = &nfs_file_mmap;
+	insert_vm_struct(current, vma);
+	merge_segments(current->mm->mmap);
 	return 0;
 }
diff -u --recursive --new-file v1.1.35/linux/fs/proc/array.c linux/fs/proc/array.c
--- v1.1.35/linux/fs/proc/array.c	Tue Jun 28 22:30:27 1994
+++ linux/fs/proc/array.c	Tue Jul 26 09:18:08 1994
@@ -410,32 +410,17 @@
 
 	for(map = (*p)->mm->mmap; map != NULL; map = map->vm_next) {
 		char str[7], *cp = str;
-		int prot = map->vm_page_prot;
-		int perms, flags;
+		int flags;
 		int end = sz + 80;	/* Length of line */
 		dev_t dev;
 		unsigned long ino;
 
-		/*
-		 * This tries to get an "rwxsp" string out of silly
-		 * intel page permissions.  The vm_area_struct should
-		 * probably have the original mmap args preserved.
-		 */
-		
-		flags = perms = 0;
+		flags = map->vm_flags;
 
-		if ((prot & PAGE_READONLY) == PAGE_READONLY)
-			perms |= PROT_READ | PROT_EXEC;
-		if (prot & (PAGE_COW|PAGE_RW)) {
-			perms |= PROT_WRITE | PROT_READ;
-			flags = prot & PAGE_COW ? MAP_PRIVATE : MAP_SHARED;
-		}
-
-		*cp++ = perms & PROT_READ ? 'r' : '-';
-		*cp++ = perms & PROT_WRITE ? 'w' : '-';
-		*cp++ = perms & PROT_EXEC ? 'x' : '-';
-		*cp++ = flags & MAP_SHARED ? 's' : '-';
-		*cp++ = flags & MAP_PRIVATE ? 'p' : '-';
+		*cp++ = flags & VM_READ ? 'r' : '-';
+		*cp++ = flags & VM_WRITE ? 'w' : '-';
+		*cp++ = flags & VM_EXEC ? 'x' : '-';
+		*cp++ = flags & VM_SHARED ? 's' : 'p';
 		*cp++ = 0;
 		
 		if (end >= PAGE_SIZE) {
diff -u --recursive --new-file v1.1.35/linux/fs/proc/link.c linux/fs/proc/link.c
--- v1.1.35/linux/fs/proc/link.c	Sat May  7 14:54:10 1994
+++ linux/fs/proc/link.c	Tue Jul 26 12:17:16 1994
@@ -71,9 +71,17 @@
 		case 5:
 			inode = p->fs->root;
 			break;
-		case 6:
-			inode = p->executable;
+		case 6: {
+			struct vm_area_struct * vma = p->mm->mmap;
+			while (vma) {
+				if (vma->vm_flags & VM_DENYWRITE) {
+					inode = vma->vm_inode;
+					break;
+				}
+				vma = vma->vm_next;
+			}
 			break;
+		}
 		default:
 			switch (ino >> 8) {
 				case 1:
diff -u --recursive --new-file v1.1.35/linux/include/linux/fs.h linux/include/linux/fs.h
--- v1.1.35/linux/include/linux/fs.h	Mon Jul 25 17:56:42 1994
+++ linux/include/linux/fs.h	Mon Jul 25 11:23:36 1994
@@ -292,7 +292,7 @@
 	int (*readdir) (struct inode *, struct file *, struct dirent *, int);
 	int (*select) (struct inode *, struct file *, int, select_table *);
 	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
-	int (*mmap) (struct inode *, struct file *, unsigned long, size_t, int, unsigned long);
+	int (*mmap) (struct inode *, struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
 	void (*release) (struct inode *, struct file *);
 	int (*fsync) (struct inode *, struct file *);
@@ -464,7 +464,7 @@
 extern int char_write(struct inode *, struct file *, char *, int);
 extern int block_write(struct inode *, struct file *, char *, int);
 
-extern int generic_mmap(struct inode *, struct file *, unsigned long, size_t, int, unsigned long);
+extern int generic_mmap(struct inode *, struct file *, struct vm_area_struct *);
 
 extern int block_fsync(struct inode *, struct file *);
 extern int file_fsync(struct inode *, struct file *);
diff -u --recursive --new-file v1.1.35/linux/include/linux/mm.h linux/include/linux/mm.h
--- v1.1.35/linux/include/linux/mm.h	Mon Jul 25 17:56:42 1994
+++ linux/include/linux/mm.h	Tue Jul 26 11:27:32 1994
@@ -34,17 +34,31 @@
 	unsigned short vm_flags;
 	struct vm_area_struct * vm_next;	/* linked list */
 	struct vm_area_struct * vm_share;	/* linked list */
-	struct inode * vm_inode;
-	unsigned long vm_offset;
 	struct vm_operations_struct * vm_ops;
+	unsigned long vm_offset;
+	struct inode * vm_inode;
+	unsigned long vm_pte;			/* shared mem */
 };
 
 /*
  * vm_flags..
  */
-#define VM_GROWSDOWN	0x01
-#define VM_GROWSUP	0x02
-#define VM_SHM		0x04
+#define VM_READ		0x0001	/* currently active flags */
+#define VM_WRITE	0x0002
+#define VM_EXEC		0x0004
+#define VM_SHARED	0x0008
+
+#define VM_MAYREAD	0x0010	/* limits for mprotect() etc */
+#define VM_MAYWRITE	0x0020
+#define VM_MAYEXEC	0x0040
+#define VM_MAYSHARE	0x0080
+
+#define VM_GROWSDOWN	0x0100	/* general info on the segment */
+#define VM_GROWSUP	0x0200
+#define VM_SHM		0x0400
+#define VM_DENYWRITE	0x0800	/* ETXTBSY on write attempts.. */
+
+#define VM_STACK_FLAGS	0x0177
 
 /*
  * These are the virtual MM functions - opening of an area, closing it (needed to
@@ -178,12 +192,8 @@
 /* mmap.c */
 extern int do_mmap(struct file * file, unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags, unsigned long off);
-typedef int (*map_mergep_fnp)(const struct vm_area_struct *,
-			      const struct vm_area_struct *, void *);
-extern void merge_segments(struct vm_area_struct *, map_mergep_fnp, void *);
+extern void merge_segments(struct vm_area_struct *);
 extern void insert_vm_struct(struct task_struct *, struct vm_area_struct *);
-extern int ignoff_mergep(const struct vm_area_struct *,
-			 const struct vm_area_struct *, void *);
 extern int do_munmap(unsigned long, size_t);
 
 #define read_swap_page(nr,buf) \
diff -u --recursive --new-file v1.1.35/linux/include/linux/mman.h linux/include/linux/mman.h
--- v1.1.35/linux/include/linux/mman.h	Tue Jan 18 10:35:52 1994
+++ linux/include/linux/mman.h	Tue Jul 26 11:28:35 1994
@@ -12,4 +12,7 @@
 #define MAP_FIXED        0x10      /* Interpret addr exactly */
 #define MAP_ANONYMOUS    0x20      /* don't use a file */
 
+#define MAP_GROWSDOWN	0x0400		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+
 #endif /* _LINUX_MMAN_H */
diff -u --recursive --new-file v1.1.35/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h
--- v1.1.35/linux/include/linux/msdos_fs.h	Mon Jul 25 17:56:43 1994
+++ linux/include/linux/msdos_fs.h	Mon Jul 25 12:01:24 1994
@@ -192,8 +192,7 @@
 extern void msdos_truncate(struct inode *inode);
 
 /* mmap.c */
-extern int msdos_mmap (struct inode *, struct file *, unsigned long, size_t
-	,int , unsigned long);
+extern int msdos_mmap(struct inode *, struct file *, struct vm_area_struct *);
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v1.1.35/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- v1.1.35/linux/include/linux/nfs_fs.h	Mon Jul 25 17:56:43 1994
+++ linux/include/linux/nfs_fs.h	Mon Jul 25 13:00:38 1994
@@ -112,8 +112,7 @@
 
 /* linux/fs/nfs/mmap.c */
 
-extern int nfs_mmap(struct inode * inode, struct file * file,
-               unsigned long addr, size_t len, int prot, unsigned long off);
+extern int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma);
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v1.1.35/linux/include/linux/sched.h linux/include/linux/sched.h
--- v1.1.35/linux/include/linux/sched.h	Mon Jul 25 17:56:43 1994
+++ linux/include/linux/sched.h	Tue Jul 26 11:56:31 1994
@@ -289,7 +289,7 @@
 /* file system info */
 	int link_count;
 	struct tty_struct *tty; /* NULL if no tty */
-	struct inode * executable;
+/* shm stuff */
 	struct shm_desc *shm;
 	struct sem_undo *semun;
 /* ldt for this task - used by Wine.  If NULL, default_ldt is used */
@@ -343,7 +343,7 @@
 /* math */	0, \
 /* comm */	"swapper", \
 /* vm86_info */	NULL, 0, 0, 0, 0, \
-/* fs info */	0,NULL,NULL, \
+/* fs info */	0,NULL, \
 /* ipc */	NULL, NULL, \
 /* ldt */	NULL, \
 /* tss */	INIT_TSS, \
diff -u --recursive --new-file v1.1.35/linux/include/linux/timer.h linux/include/linux/timer.h
--- v1.1.35/linux/include/linux/timer.h	Mon Jul 25 17:56:43 1994
+++ linux/include/linux/timer.h	Mon Jul 25 12:23:03 1994
@@ -80,4 +80,10 @@
 extern void add_timer(struct timer_list * timer);
 extern int  del_timer(struct timer_list * timer);
 
+extern inline void init_timer(struct timer_list * timer)
+{
+	timer->next = NULL;
+	timer->prev = NULL;
+}
+
 #endif
diff -u --recursive --new-file v1.1.35/linux/ipc/shm.c linux/ipc/shm.c
--- v1.1.35/linux/ipc/shm.c	Fri Jul 22 16:41:02 1994
+++ linux/ipc/shm.c	Tue Jul 26 11:26:11 1994
@@ -404,17 +404,19 @@
 	vma->vm_task = current;
 	vma->vm_start = addr;
 	vma->vm_end = addr + len;
+	vma->vm_flags = VM_SHM | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC;
 	if (readonly)
 		vma->vm_page_prot = PAGE_READONLY;
-	else
+	else {
+		vma->vm_flags |= VM_MAYWRITE | VM_WRITE;
 		vma->vm_page_prot = PAGE_SHARED;
-	vma->vm_flags = VM_SHM;
+	}
 	vma->vm_share = NULL;
 	vma->vm_inode = NULL;
 	vma->vm_offset = 0;
 	vma->vm_ops = &shm_vm_ops;
 	insert_vm_struct(current, vma);
-	merge_segments(current->mm->mmap, NULL, NULL);
+	merge_segments(current->mm->mmap);
 	return 0;
 }
 
@@ -497,11 +499,6 @@
 	}
 
 	shp->shm_nattch++;            /* prevent destruction */
-	if (addr < current->mm->end_data) {
-		iput (current->executable);
-		current->executable = NULL;
-/*		current->end_data = current->end_code = 0; */
-	}
 
 	if ((err = shm_map (shmd, shmflg & SHM_REMAP))) {
 		if (--shp->shm_nattch <= 0 && shp->shm_perm.mode & SHM_DEST)
diff -u --recursive --new-file v1.1.35/linux/kernel/exit.c linux/kernel/exit.c
--- v1.1.35/linux/kernel/exit.c	Fri Jul 22 16:41:02 1994
+++ linux/kernel/exit.c	Tue Jul 26 11:25:25 1994
@@ -400,8 +400,6 @@
 	current->fs->pwd = NULL;
 	iput(current->fs->root);
 	current->fs->root = NULL;
-	iput(current->executable);
-	current->executable = NULL;
 }
 
 NORET_TYPE void do_exit(long code)
diff -u --recursive --new-file v1.1.35/linux/kernel/fork.c linux/kernel/fork.c
--- v1.1.35/linux/kernel/fork.c	Mon Jul 18 14:48:31 1994
+++ linux/kernel/fork.c	Tue Jul 26 11:25:11 1994
@@ -156,8 +156,6 @@
 		current->fs->pwd->i_count++;
 	if (current->fs->root)
 		current->fs->root->i_count++;
-	if (current->executable)
-		current->executable->i_count++;
 }
 
 #define IS_CLONE (regs.orig_eax == __NR_clone)
diff -u --recursive --new-file v1.1.35/linux/mm/Makefile linux/mm/Makefile
--- v1.1.35/linux/mm/Makefile	Wed Dec  1 14:44:15 1993
+++ linux/mm/Makefile	Mon Jul 25 22:03:14 1994
@@ -14,7 +14,7 @@
 .c.s:
 	$(CC) $(CFLAGS) -S $<
 
-OBJS	= memory.o swap.o mmap.o kmalloc.o vmalloc.o
+OBJS	= memory.o swap.o mmap.o mprotect.o kmalloc.o vmalloc.o
 
 mm.o: $(OBJS)
 	$(LD) -r -o mm.o $(OBJS)
diff -u --recursive --new-file v1.1.35/linux/mm/mmap.c linux/mm/mmap.c
--- v1.1.35/linux/mm/mmap.c	Mon Jul 25 17:56:44 1994
+++ linux/mm/mmap.c	Tue Jul 26 11:32:36 1994
@@ -16,9 +16,8 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 
-static int anon_map(struct inode *, struct file *,
-		    unsigned long, size_t, int,
-		    unsigned long);
+static int anon_map(struct inode *, struct file *, struct vm_area_struct *);
+
 /*
  * description of effects of mapping type and prot in current implementation.
  * this is due to the limited x86 page protection hardware.  The expected
@@ -40,6 +39,7 @@
 	unsigned long prot, unsigned long flags, unsigned long off)
 {
 	int mask, error;
+	struct vm_area_struct * vma;
 
 	if ((len = PAGE_ALIGN(len)) == 0)
 		return addr;
@@ -47,13 +47,17 @@
 	if (addr > TASK_SIZE || len > TASK_SIZE || addr > TASK_SIZE-len)
 		return -EINVAL;
 
+	/* offset overflow? */
+	if (off + len < off)
+		return -EINVAL;
+
 	/*
 	 * do simple checking here so the lower-level routines won't have
 	 * to. we assume access permissions have been handled by the open
 	 * of the memory object, so we don't do any here.
 	 */
 
-	if (file != NULL)
+	if (file != NULL) {
 		switch (flags & MAP_TYPE) {
 		case MAP_SHARED:
 			if ((prot & PROT_WRITE) && !(file->f_mode & 2))
@@ -67,6 +71,9 @@
 		default:
 			return -EINVAL;
 		}
+	} else if ((flags & MAP_TYPE) == MAP_SHARED)
+		return -EINVAL;
+
 	/*
 	 * obtain the address to map to. we verify (or select) it and ensure
 	 * that it represents a valid section of the address space.
@@ -105,7 +112,7 @@
 	 */
 	if (file && (!file->f_op || !file->f_op->mmap))
 		return -ENODEV;
-	mask = 0;
+	mask = PAGE_PRESENT;
 	if (prot & (PROT_READ | PROT_EXEC))
 		mask |= PAGE_READONLY;
 	if (prot & PROT_WRITE)
@@ -113,19 +120,44 @@
 			mask |= PAGE_COPY;
 		else
 			mask |= PAGE_SHARED;
-	if (!mask) /* PROT_NONE */
-		mask = PAGE_PRESENT;	/* none of PAGE_USER, PAGE_RW, PAGE_COW */
 
+	vma = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!vma)
+		return -ENOMEM;
+
+	vma->vm_task = current;
+	vma->vm_start = addr;
+	vma->vm_end = addr + len;
+	vma->vm_page_prot = mask;
+	vma->vm_flags = prot & (VM_READ | VM_WRITE | VM_EXEC);
+	vma->vm_flags |= flags & (VM_GROWSDOWN | VM_DENYWRITE);
+
+	if (file) {
+		if (file->f_mode & 1)
+			vma->vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+		if (flags & MAP_SHARED) {
+			vma->vm_flags |= VM_SHARED | VM_MAYSHARE;
+			if (!(file->f_mode & 2))
+				vma->vm_flags &= ~VM_MAYWRITE;
+		}
+	} else
+		vma->vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+	vma->vm_ops = NULL;
+	vma->vm_offset = off;
+	vma->vm_inode = NULL;
+	vma->vm_pte = 0;
+
 	do_munmap(addr, len);	/* Clear old maps */
 
 	if (file)
-		error = file->f_op->mmap(file->f_inode, file, addr, len, mask, off);
+		error = file->f_op->mmap(file->f_inode, file, vma);
 	else
-		error = anon_map(NULL, NULL, addr, len, mask, off);
+		error = anon_map(NULL, NULL, vma);
 	
 	if (!error)
 		return addr;
 
+	kfree(vma);
 	if (!current->errno)
 		current->errno = -error;
 	return -1;
@@ -225,12 +257,6 @@
 	insert_vm_struct(current, mpnt);
 }
 
-
-asmlinkage int sys_mprotect(unsigned long addr, size_t len, unsigned long prot)
-{
-	return -EINVAL; /* Not implemented yet */
-}
-
 asmlinkage int sys_munmap(unsigned long addr, size_t len)
 {
 	return do_munmap(addr, len);
@@ -307,16 +333,14 @@
 }
 
 /* This is used for a general mmap of a disk file */
-int generic_mmap(struct inode * inode, struct file * file,
-	unsigned long addr, size_t len, int prot, unsigned long off)
+int generic_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
 {
-  	struct vm_area_struct * mpnt;
 	extern struct vm_operations_struct file_mmap;
 	struct buffer_head * bh;
 
-	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported right now */
+	if (vma->vm_page_prot & PAGE_RW)	/* only PAGE_COW or read-only supported right now */
 		return -EINVAL;
-	if (off & (inode->i_sb->s_blocksize - 1))
+	if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
 		return -EINVAL;
 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
 		return -EACCES;
@@ -330,23 +354,12 @@
 	}
 	brelse(bh);
 
-	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
-	if (!mpnt)
-		return -ENOMEM;
-
-	unmap_page_range(addr, len);	
-	mpnt->vm_task = current;
-	mpnt->vm_start = addr;
-	mpnt->vm_end = addr + len;
-	mpnt->vm_page_prot = prot;
-	mpnt->vm_flags = 0;
-	mpnt->vm_share = NULL;
-	mpnt->vm_inode = inode;
+	unmap_page_range(vma->vm_start, vma->vm_end - vma->vm_start);
+	vma->vm_inode = inode;
 	inode->i_count++;
-	mpnt->vm_offset = off;
-	mpnt->vm_ops = &file_mmap;
-	insert_vm_struct(current, mpnt);
-	merge_segments(current->mm->mmap, NULL, NULL);
+	vma->vm_ops = &file_mmap;
+	insert_vm_struct(current, vma);
+	merge_segments(current->mm->mmap);
 	
 	return 0;
 }
@@ -388,8 +401,7 @@
  * Redundant vm_area_structs are freed.
  * This assumes that the list is ordered by address.
  */
-void merge_segments(struct vm_area_struct *mpnt,
-		    map_mergep_fnp mergep, void *mpd)
+void merge_segments(struct vm_area_struct *mpnt)
 {
 	struct vm_area_struct *prev, *next;
 
@@ -400,32 +412,29 @@
 	    mpnt != NULL;
 	    prev = mpnt, mpnt = next)
 	{
-		int mp;
-
 		next = mpnt->vm_next;
-		
-		if (mergep == NULL)
-		{
-			unsigned long psz = prev->vm_end - prev->vm_start;
-			mp = prev->vm_offset + psz == mpnt->vm_offset;
-		}
-		else
-			mp = (*mergep)(prev, mpnt, mpd);
 
 		/*
-		 * Check they are compatible.
-		 * and the like...
-		 * What does the share pointer mean?
+		 * To share, we must have the same inode, operations.. 
 		 */
-		if (prev->vm_ops != mpnt->vm_ops ||
-		    prev->vm_page_prot != mpnt->vm_page_prot ||
-		    prev->vm_inode != mpnt->vm_inode ||
-		    prev->vm_end != mpnt->vm_start ||
-		    !mp ||
-		    prev->vm_flags != mpnt->vm_flags ||
-		    prev->vm_share != mpnt->vm_share ||		/* ?? */
-		    prev->vm_next != mpnt)			/* !!! */
+		if (mpnt->vm_inode != prev->vm_inode)
+			continue;
+		if (mpnt->vm_pte != prev->vm_pte)
+			continue;
+		if (mpnt->vm_ops != prev->vm_ops)
+			continue;
+		if (mpnt->vm_page_prot != prev->vm_page_prot ||
+		    mpnt->vm_flags != prev->vm_flags)
+			continue;
+		if (prev->vm_end != mpnt->vm_start)
 			continue;
+		/*
+		 * and if we have an inode, the offsets must be contiguous..
+		 */
+		if (mpnt->vm_inode != NULL) {
+			if (prev->vm_offset + prev->vm_end - prev->vm_start != mpnt->vm_offset)
+				continue;
+		}
 
 		/*
 		 * merge prev with mpnt and set up pointers so the new
@@ -443,41 +452,12 @@
  * Map memory not associated with any file into a process
  * address space.  Adjecent memory is merged.
  */
-static int anon_map(struct inode *ino, struct file * file,
-		    unsigned long addr, size_t len, int mask,
-		    unsigned long off)
+static int anon_map(struct inode *ino, struct file * file, struct vm_area_struct * vma)
 {
-  	struct vm_area_struct * mpnt;
-
-	if (zeromap_page_range(addr, len, mask))
+	if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -ENOMEM;
 
-	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
-	if (!mpnt)
-		return -ENOMEM;
-
-	mpnt->vm_task = current;
-	mpnt->vm_start = addr;
-	mpnt->vm_end = addr + len;
-	mpnt->vm_page_prot = mask;
-	mpnt->vm_flags = 0;
-	mpnt->vm_share = NULL;
-	mpnt->vm_inode = NULL;
-	mpnt->vm_offset = 0;
-	mpnt->vm_ops = NULL;
-	insert_vm_struct(current, mpnt);
-	merge_segments(current->mm->mmap, ignoff_mergep, NULL);
-
+	insert_vm_struct(current, vma);
+	merge_segments(current->mm->mmap);
 	return 0;
-}
-
-/* Merge, ignoring offsets */
-int ignoff_mergep(const struct vm_area_struct *m1,
-		  const struct vm_area_struct *m2,
-		  void *data)
-{
-	if (m1->vm_inode != m2->vm_inode)	/* Just to be sure */
-		return 0;
-
-	return (struct inode *)data == m1->vm_inode;
 }
diff -u --recursive --new-file v1.1.35/linux/mm/mprotect.c linux/mm/mprotect.c
--- v1.1.35/linux/mm/mprotect.c	Thu Jan  1 02:00:00 1970
+++ linux/mm/mprotect.c	Tue Jul 26 07:34:15 1994
@@ -0,0 +1,199 @@
+/*
+ *	linux/mm/mprotect.c
+ *
+ *  (C) Copyright 1994 Linus Torvalds
+ */
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#define CHG_MASK (PAGE_MASK | PAGE_ACCESSED | PAGE_DIRTY | PAGE_PWT | PAGE_PCD)
+
+static void change_protection(unsigned long start, unsigned long end, int prot)
+{
+	unsigned long *page_table, *dir;
+	unsigned long page, offset;
+	int nr;
+
+	dir = PAGE_DIR_OFFSET(current->tss.cr3, start);
+	offset = (start >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
+	nr = (end - start) >> PAGE_SHIFT;
+	while (nr > 0) {
+		page = *dir;
+		dir++;
+		if (!(page & PAGE_PRESENT)) {
+			nr = nr - PTRS_PER_PAGE + offset;
+			offset = 0;
+			continue;
+		}
+		page_table = offset + (unsigned long *) (page & PAGE_MASK);
+		offset = PTRS_PER_PAGE - offset;
+		if (offset > nr)
+			offset = nr;
+		nr = nr - offset;
+		do {
+			page = *page_table;
+			if (page & PAGE_PRESENT)
+				*page_table = (page & CHG_MASK) | prot;
+			++page_table;
+		} while (--offset);
+	}
+	return;
+}
+
+static inline int mprotect_fixup_all(struct vm_area_struct * vma,
+	int newflags, int prot)
+{
+	vma->vm_flags = newflags;
+	vma->vm_page_prot = prot;
+	merge_segments(current->mm->mmap);
+	return 0;
+}
+
+static inline int mprotect_fixup_start(struct vm_area_struct * vma,
+	unsigned long end,
+	int newflags, int prot)
+{
+	struct vm_area_struct * new;
+
+	new = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!new)
+		return -ENOMEM;
+	*new = *vma;
+	vma->vm_start = end;
+	new->vm_end = end;
+	vma->vm_offset += vma->vm_start - new->vm_start;
+	new->vm_flags = newflags;
+	new->vm_page_prot = prot;
+	if (new->vm_inode)
+		new->vm_inode->i_count++;
+	insert_vm_struct(current, new);
+	merge_segments(current->mm->mmap);
+	return 0;
+}
+
+static inline int mprotect_fixup_end(struct vm_area_struct * vma,
+	unsigned long start,
+	int newflags, int prot)
+{
+	struct vm_area_struct * new;
+
+	new = kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!new)
+		return -ENOMEM;
+	*new = *vma;
+	vma->vm_end = start;
+	new->vm_start = start;
+	new->vm_offset += new->vm_start - vma->vm_start;
+	new->vm_flags = newflags;
+	new->vm_page_prot = prot;
+	if (new->vm_inode)
+		new->vm_inode->i_count++;
+	insert_vm_struct(current, new);
+	merge_segments(current->mm->mmap);
+	return 0;
+}
+
+static inline int mprotect_fixup_middle(struct vm_area_struct * vma,
+	unsigned long start, unsigned long end,
+	int newflags, int prot)
+{
+	int error;
+	unsigned long tmpflags, tmpprot;
+
+	tmpflags = vma->vm_flags;
+	tmpprot = vma->vm_page_prot;
+	vma->vm_flags = newflags;
+	vma->vm_page_prot = prot;
+	error = mprotect_fixup_end(vma, end, tmpflags, tmpprot);
+	if (!error)
+		error = mprotect_fixup_start(vma, start, tmpflags, tmpprot);
+	return error;
+}
+
+static int mprotect_fixup(struct vm_area_struct * vma, 
+	unsigned long start, unsigned long end, unsigned int newflags)
+{
+	int prot, error;
+
+	if (newflags == vma->vm_flags)
+		return 0;
+	prot = PAGE_PRESENT;
+	if (newflags & (VM_READ | VM_EXEC))
+		prot |= PAGE_READONLY;
+	if (newflags & VM_WRITE)
+		if (newflags & VM_SHARED)
+			prot |= PAGE_SHARED;
+		else
+			prot |= PAGE_COPY;
+
+	if (start == vma->vm_start)
+		if (end == vma->vm_end)
+			error = mprotect_fixup_all(vma, newflags, prot);
+		else
+			error = mprotect_fixup_start(vma, end, newflags, prot);
+	else if (end == vma->vm_end)
+		error = mprotect_fixup_end(vma, start, newflags, prot);
+	else
+		error = mprotect_fixup_middle(vma, start, end, newflags, prot);
+
+	if (error)
+		return error;
+
+	change_protection(start, end, prot);
+	return 0;
+}
+
+asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot)
+{
+	unsigned long end;
+	struct vm_area_struct * vma;
+
+	if (start & ~PAGE_MASK)
+		return -EINVAL;
+	len = (len + ~PAGE_MASK) & PAGE_MASK;
+	end = start + len;
+	if (end < start)
+		return -EINVAL;
+	if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+		return -EINVAL;
+	if (end == start)
+		return 0;
+	for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
+		if (!vma)
+			return -EFAULT;
+		if (vma->vm_end > start)
+			break;
+	}
+	if (vma->vm_start > start)
+		return -EFAULT;
+
+	for ( ; ; ) {
+		int error;
+		unsigned int newflags;
+
+		newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
+		if ((newflags & ~(newflags >> 4)) & 0xf)
+			return -EACCES;
+
+		if (vma->vm_end >= end)
+			return mprotect_fixup(vma, start, end, newflags);
+
+		error = mprotect_fixup(vma, start, vma->vm_end, newflags);
+		if (error)
+			return error;
+		start = vma->vm_end;
+		vma = vma->vm_next;
+		if (!vma || vma->vm_start != start)
+			return -EFAULT;
+	}
+}
diff -u --recursive --new-file v1.1.35/linux/mm/swap.c linux/mm/swap.c
--- v1.1.35/linux/mm/swap.c	Mon Jul 25 17:56:45 1994
+++ linux/mm/swap.c	Tue Jul 26 10:59:04 1994
@@ -303,6 +303,7 @@
 		return 0;
 	
 	if ((PAGE_DIRTY & page) && delete_from_swap_cache(page))  {
+		*table_ptr &= ~PAGE_ACCESSED;
 		return 0;
 	}
 	if (PAGE_ACCESSED & page) {
@@ -321,7 +322,6 @@
 		free_page(page);
 		return 1;
 	}
-
         if ((entry = find_in_swap_cache(page)))  {
 		if (mem_map[MAP_NR(page)] != 1) {
 			*table_ptr |= PAGE_DIRTY;
