RE: patch for migshm

"Moshe Bar" <moshe-ay74M1d3r6RWk0Htik3J/[email protected]>
Newsgroups gmane.linux.cluster.openmosix.devel
Organization Morpheus Holdings, Inc
Message-ID <[email protected]>
Ratna

Thanks a lot of this. Lots of people have been asking for it. I will compile
and test this week-end when I get back home. 

Many thanks

Moshe 

-----Original Message-----
From: Ratna Manoj Bolla [mailto:[email protected]] 
Sent: Monday, May 08, 2006 5:35 AM
To: openmosix-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: moshe-ay74M1d3r6RWk0Htik3J/[email protected]
Subject: patch for migshm

Below is the patch for MigShm.

- No STAY_FOR_MONKEY flag
- implemented Distributed shared memory.
- MAP_SHARED mappings can now migrate.


-more debugging has to be done.
plz report bugs and suggestions.


below is my one of the test program followed by patch.

#include<stdio.h>
#include<sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
char *pid2proc_path(int);
char path[50];
int b[80];
main() {
 	int fd = open("om_file",O_RDWR);
 	char *a = mmap(0,4096*15,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
 	int i = 0;
 	unsigned long k=0;
 	char *b =a;// mmap(0,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);
 	fork();
 	fork();
 	fork();
 	fork();
 	while(k++ <= 0xffffff00); k=0;
  	while(k++ <= 0xffffff00); k=0;
   //	while(k++ <= 0xffffff00); k=0;
  //	while(k++ <= 0xffffff00); k=0;
//	while(k++ <= 0xffffff00); k=0;

 	char ch = 'A';
 	while(1) {
 		i++;
 		if(i== 15000)
 			break;
 	//	sleep(1);
 		if(ch == 'Z')
 			ch = 'A';
 		*a = ch;
 	//	sleep(1);
 		printf("p:%d-%c\n",i,*a);
 		a+=3;
 		ch++;
         }
}

Patch:

diff -Naur linux-2.4.26-om1/fs/file_table.c
linux-2.4.26-om1-o/fs/file_table.c
--- linux-2.4.26-om1/fs/file_table.c	2006-05-08 15:01:47.000000000 +0530
+++ linux-2.4.26-om1-o/fs/file_table.c	2006-05-07 17:56:02.000000000 +0530
@@ -13,6 +13,7 @@
  #include <linux/smp_lock.h>
  #include <linux/iobuf.h>

+#include <hpc/mig_shm.h>
  /* sysctl tunables... */
  struct files_stat_struct files_stat = {0, 0, NR_FILE};

@@ -104,8 +105,12 @@
  	struct inode * inode = dentry->d_inode;

  	if (atomic_dec_and_test(&file->f_count)) {
+#ifdef CONFIG_MOSIX 
+		if(current->mosix.dflags & DREMOTE) 
+			shm_send_message(current->mosix.deppe,(struct
shm_page *)(home_file(file)),NULL,PUT_FILE);
+#endif /* CONFIG_MOSIX */
  		locks_remove_flock(file);
-
+
  		if (file->f_iobuf)
  			free_kiovec(1, &file->f_iobuf);

diff -Naur linux-2.4.26-om1/fs/read_write.c
linux-2.4.26-om1-o/fs/read_write.c
--- linux-2.4.26-om1/fs/read_write.c	2006-05-08 15:01:50.000000000 +0530
+++ linux-2.4.26-om1-o/fs/read_write.c	2006-05-07 17:56:02.000000000 +0530
@@ -169,10 +169,26 @@
  }
  #endif

+#ifdef CONFIG_MOSIX
+
+extern void
+put_pages(struct address_space *mapping,loff_t offset,size_t count,int
writer,unsigned long error);
+
+extern unsigned long
+get_pages(struct address_space *mapping,loff_t offset,size_t count,int
writer);
+
+#endif /* CONFIG_MOSIX */
+
+
+
  asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count)
  {
  	ssize_t ret;
  	struct file * file;
+#ifdef CONFIG_MOSIX
+	unsigned long error=0;
+	loff_t offset;
+#endif /* CONFIG_MOSIX */

  #ifdef CONFIG_MOSIX_DFSA
  	dfsa_syscall_on_file(fd, 1);
@@ -186,10 +202,23 @@
  			if (!ret) {
  				ssize_t (*read)(struct file *, char *,
size_t, loff_t *);
  				ret = -EINVAL;
-				if (file->f_op && (read = file->f_op->read)
!= NULL)
-					ret = read(file, buf, count,
&file->f_pos);
+				if (file->f_op && (read = file->f_op->read)
!= NULL) 
+#ifdef CONFIG_MOSIX
+				{
+					error =
get_pages(file->f_dentry->d_inode->i_mapping,(offset =
file->f_pos),count,0);
+					if(!error)
+#endif /* CONFIG_MOSIX */ 
+						ret = read(file, buf, count,
&file->f_pos); 
+#ifdef CONFIG_MOSIX 
+
put_pages(file->f_dentry->d_inode->i_mapping,offset,count,0,error); 
+				}
+#endif /* CONFIG_MOSIX */
  			}
  		}
+
+		if(error)
+			ret = -1;
+
  		if (ret > 0)
  			dnotify_parent(file->f_dentry, DN_ACCESS);
  		fput(file);
@@ -201,6 +230,10 @@
  {
  	ssize_t ret;
  	struct file * file;
+#ifdef CONFIG_MOSIX
+	unsigned long error=0;
+	loff_t offset;
+#endif /* CONFIG_MOSIX */

  #ifdef CONFIG_MOSIX_DFSA
  	dfsa_syscall_on_file(fd, 1);
@@ -215,10 +248,23 @@
  			if (!ret) {
  				ssize_t (*write)(struct file *, const char
*, size_t, loff_t *);
  				ret = -EINVAL;
-				if (file->f_op && (write =
file->f_op->write) != NULL)
-					ret = write(file, buf, count,
&file->f_pos);
-			}
+				if (file->f_op && (write =
file->f_op->write) != NULL) 
+#ifdef CONFIG_MOSIX
+				{
+					error =
get_pages(file->f_dentry->d_inode->i_mapping,(offset =
file->f_pos),count,1);
+ 
+					if(!error)
+#endif /* CONFIG_MOSIX */
+						ret = write(file, buf,
count, &file->f_pos);
+#ifdef CONFIG_MOSIX 
+
put_pages(file->f_dentry->d_inode->i_mapping,offset,count,1,error);
+                                }
+#endif /* CONFIG_MOSIX */ 
+			}
  		}
+
+		if(error)
+			ret = -1;
  		if (ret > 0)
  			dnotify_parent(file->f_dentry, DN_MODIFY);
  		fput(file);
diff -Naur linux-2.4.26-om1/hpc/comm.c linux-2.4.26-om1-o/hpc/comm.c
--- linux-2.4.26-om1/hpc/comm.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/comm.c	2006-05-07 17:56:02.000000000 +0530
@@ -31,7 +31,6 @@

  #define MIG_DAEMON_PORT		0x3412
  #define INFO_DAEMON_PORT	0x3415
-
  /*
   * mosix specific data per contact
   */
@@ -65,7 +64,7 @@
  #define	COMM_SOCKET_BUFFER	131072

  #define COMM_REMOTE_TIMO	((unsigned long) 200*HZ)	/* changed
form 300 */
-#define COMM_CONNECT_TIMO	((unsigned long) 4*HZ)	/* changed from 5 */
+#define COMM_CONNECT_TIMO	((unsigned long) 10*HZ)	/* changed from 5 */
  #define COMM_RECONN_TIMO	((unsigned long) 10*HZ)

  #ifdef CONFIG_MOSIX_DFSA
@@ -171,7 +170,6 @@
  static int comm_waitaccept(void);
  static int comm_poll(int, int, unsigned long);
  static void comm_data_ready(struct sock *, int);
-static int comm_getname(struct socket *, struct sockaddr *);
  static void comm_shutdown(mosix_link *);

  static inline struct socket *comm_set_address(int, struct sockaddr *,
int);
@@ -315,8 +313,6 @@
  	him = ((int *) ptr)[0];
  	me = ((int *) ptr)[1];

-	if (him & 0x80000000)
-		rinode_flush_files(him & ~0x80000000);
  	if (comm_getpeer(current->mosix.contact) == (him & 0x7fffffff)
  	    && PE == me)
  		ret = 2 * sizeof (int);
@@ -367,6 +363,8 @@
  */

  	switch (mos) {
+	case MIGSHM_COMM: 
+	case COMM_MIGSHM:
  	case COMM_INFO:
  		sock->sk->data_ready = comm_data_ready;
  		break;
@@ -493,6 +491,8 @@
  	case COMM_LOOSE:
  		bind = 0;
  		/* fall through */
+	case MIGSHM_COMM:
+	case COMM_MIGSHM:
  	case COMM_INFO:
  		listen = 0;
  		/* fall through */
@@ -763,7 +763,7 @@
  	mosix_panic("comm_free() # 1");

        out:
-
+		return;
  }

  /*
@@ -1564,6 +1564,7 @@
  	return (error);
  }

+unsigned long AVG_TRIES = 2;
  /*
   * comm_recvfrom() - receive a datagram from someone
   * NOTE NOTE NOTE:  the timeout is in microseconds -- NOT ticks!
@@ -1580,7 +1581,14 @@
  	int error;
  	int nrecv = len, msgflg = 0;
  	DECLARE_WAITQUEUE(wait, current);
+	unsigned long tries = LONG_MAX;
+	unsigned long for_avg = 0;

+	if (timo == GTIME_OUT)
+		tries = 3 * AVG_TRIES-1;
+	else if (timo == INT_TIME_OUT)
+		tries = 4 * AVG_TRIES * NPE - 1;
+	else
  	if (timo) {
  #if MILLION % HZ
  		timo = timo * HZ / MILLION;
@@ -1591,13 +1599,13 @@
  	oldfs = get_fs();
  	set_fs(KERNEL_DS);

-	if (timo)
-		msgflg |= MSG_DONTWAIT;
+	if(timo == GTIME_OUT || timo == INT_TIME_OUT || !timo)
+		timo = MAX_SCHEDULE_TIMEOUT;
  	else
-		timo = MAX_SCHEDULE_TIMEOUT;
+		msgflg |= MSG_DONTWAIT;

  	add_wait_queue(mlink->sock->sk->sleep, &wait);
-	while (1) {
+	while (tries) {
  		set_current_state(msgflg ? TASK_UNINTERRUPTIBLE :
  				  TASK_INTERRUPTIBLE);

@@ -1622,6 +1630,10 @@
  			error = -EINTR;
  			break;
  		}
+		if(tries != LONG_MAX) {
+			tries--;
+			for_avg++;
+		}
  	}
  	remove_wait_queue(mlink->sock->sk->sleep, &wait);
  	set_current_state(TASK_RUNNING);
@@ -1629,6 +1641,12 @@

  	if (msg.msg_flags & MSG_TRUNC) {
  		error = -EDIST;
+	} else if(!tries)
+		error = -ETIME;
+	else  if (tries != LONG_MAX )  {
+		AVG_TRIES = (AVG_TRIES + for_avg) / 2;
+		if(AVG_TRIES < 2)
+			AVG_TRIES = 2;
  	}

  	return (error);
@@ -1681,7 +1699,7 @@
  /*
   * comm_getname: fill in our name
   */
-static int
+int
  comm_getname(struct socket *sock, struct sockaddr *saddr)
  {
  	switch (comm_type) {
@@ -1741,6 +1759,7 @@
  	case COMM_TOADDR:
  		/* address was set by the caller */
  		break;
+	case COMM_MIGSHM:
  	case COMM_INFO:
  		proto = IPPROTO_UDP;
  		type = SOCK_DGRAM;
@@ -1751,10 +1770,17 @@
  		sa->sin_addr.s_addr = INADDR_ANY;
  		if (mos == COMM_MIGD)
  			sa->sin_port = MIG_DAEMON_PORT;
-		else
+		else if(mos == COMM_INFO)
  			sa->sin_port = INFO_DAEMON_PORT;
+		else  if(mos == COMM_MIGSHM)
+			sa->sin_port = MIGSHM_DEAMON_PORT;
  		break;
  	case COMM_ACCEPT:
+	case MIGSHM_COMM:
+		if(mos == MIGSHM_COMM) {
+			type = SOCK_DGRAM;
+                	proto = IPPROTO_UDP;
+		}
  		memset((void *) sa, 0, sizeof (struct sockaddr_in));
  		sa->sin_family = AF_INET;
  		sa->sin_addr.s_addr = INADDR_ANY;
diff -Naur linux-2.4.26-om1/hpc/deputy.c linux-2.4.26-om1-o/hpc/deputy.c
--- linux-2.4.26-om1/hpc/deputy.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/deputy.c	2006-05-07 17:56:02.000000000 +0530
@@ -24,6 +24,9 @@
  #include <asm/mmu_context.h>
  #include <linux/smp_lock.h>
  #include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
  #ifdef CONFIG_MOSIX_DFSA
  #include <hpc/dfsa.h>
  #endif /* CONFIG_MOSIX_DFSA */
@@ -343,27 +346,30 @@
  deputy_handle_interim_request(int type, void *head, int hlen)
  {
  	switch (type) {
-	case REM_NOTHING:
-		comm_free(head);
-		return (comm_send(REM_NOTHING | REPLY, NULL, 0, NULL, 0,
0));
-	case REM_PAGE:
-		return (deputy_bring_page((struct bring_page_h *) head));
-	case REM_GETTSC:
-		return (deputy_tsc());
-	case REM_MORESTRINGS:
-		return (deputy_more_strings
-			((struct execve_more_strings_h *) head));
-	case REM_BRING_ME_REGS:
-		return (deputy_bring_me_regs((unsigned long *) head));
-	case REM_GETALOAD:
-		return (send_local_aload(REM_GETALOAD | REPLY));
-	default:
-		printk("Process %s, uid=%d, received an unexpected "
-		       "urgent request\n" "(type 0x%x) from the "
-		       "remote site where it was running\n",
-		       desc_mostask(NULL), current->uid, type);
-		comm_free(head);
-		return (-EDIST);
+
+		case REM_UPGRADE:
+			return(deputy_upgrade((struct upgrade_h *)head));
+		case REM_NOTHING:
+			comm_free(head);
+			return (comm_send(REM_NOTHING | REPLY, NULL, 0,
NULL, 0, 0));
+		case REM_PAGE:
+			return (deputy_bring_page((struct bring_page_h *)
head));
+		case REM_GETTSC:
+			return (deputy_tsc());
+		case REM_MORESTRINGS:
+			return (deputy_more_strings
+				((struct execve_more_strings_h *) head));
+		case REM_BRING_ME_REGS:
+			return (deputy_bring_me_regs((unsigned long *)
head));
+		case REM_GETALOAD:
+			return (send_local_aload(REM_GETALOAD | REPLY));
+		default:
+			printk("Process %s, uid=%d, received an unexpected "
+		       		"urgent request\n" "(type 0x%x) from the "
+		       		"remote site where it was running\n",
+		       	desc_mostask(NULL), current->uid, type);
+			comm_free(head);
+			return (-EDIST);
  	}
  }

@@ -431,29 +437,29 @@

  unsigned long
  mosix_deputy_mmap(struct file *fp, unsigned long addr, int fixed,
-		  unsigned long len, unsigned long flags, unsigned long off,
-		  off_t isize, nopage_t nopage)
+                unsigned long len, unsigned long flags, unsigned long off,
+                off_t isize, nopage_t nopage)
  {
-	struct mmap_parameters_h mp;
-	int error;
-	unsigned long result;
-
-	mp.addr = addr;
-	mp.fixed = fixed;
-	mp.len = len;
-	mp.flags = flags;
-	mp.pgoff = off;
-	mp.origin = PE;
-	if ((mp.fp = fp)) {
-		mp.dp = fp->f_dentry;
-		mp.uniq = mp.fp->f_dentry->d_inode->i_unique;
-		mp.isize = mp.fp->f_dentry->d_inode->i_size;
-	}
-	mp.nopage = nopage;
-	if ((error = deputy_request(DEP_MMAP, &mp, sizeof (mp), NULL, 0, 0,
-				    (void **) &result, -sizeof (result))))
-		return (error);
-	return (result);
+      struct mmap_parameters_h mp;
+         int error;
+      unsigned long result;
+
+      mp.addr = addr;
+      mp.fixed = fixed;
+      mp.len = len;
+      mp.flags = flags;
+      mp.pgoff = off;
+      mp.origin = PE;
+      if ((mp.fp = fp)) {
+              mp.dp = fp->f_dentry;
+              mp.uniq = mp.fp->f_dentry->d_inode->i_unique;
+              mp.isize = mp.fp->f_dentry->d_inode->i_size;
+      }
+      mp.nopage = nopage;
+      if ((error = deputy_request(DEP_MMAP, &mp, sizeof (mp), NULL, 0, 0,
+                                  (void **) &result, -sizeof (result))))
+              return (error);
+      return (result);
  }

  long
@@ -519,9 +525,6 @@
  		case FATAL_SIGSEGV:
  			force_sig(SIGSEGV, current);
  			break;
-		case REMOTE_FILE_RELEASED:
-			mosix_rebuild_file_list();
-			break;
  		case SIGSEGV:
  		case SIGKILL:
  		case SIGVTALRM:
@@ -910,31 +913,118 @@
  }

  int
+deputy_upgrade(struct upgrade_h *u)
+{
+	struct shm_page *shm_page = u->rem_shm_page_addr;
+	struct page *page = NULL;
+	struct shm_page_ret_h r;
+        int err;
+
+
+       	spin_lock(&shm_page->shm_lock);
+	if((shm_page->state & PERM_ERR) || (shm_page->state & UPGRADE_ERR))
+		r.ret = 2;
+	else
+      	if(((shm_page->state & STATE_MASK) == SHARED) && !(shm_page->state &
DROPPING) && (!shm_page->readers)) {
+           	shm_page->state &=  ~SHARED;
+           	shm_page->state |= BUSY_EXCLUSIVE;
+
+             	spin_unlock(&shm_page->shm_lock);
+             	page = find_get_page(shm_page->mapping,shm_page->index);
+
+             	if(page) {
+                   	invalidate(shm_page,page,1);
+                     	page_cache_release(page);
+             	}
+
+
+		shm_send_message(0,shm_page,NULL,DROP_NEXTPREV);
+
+		shm_page->next = shm_page->prev = PE;
+		shm_page->next_addr = shm_page->prev_addr = shm_page;
+
+           	spin_lock(&shm_page->shm_lock);
+           	shm_page->owner = current->mosix.whereami;
+            	shm_page->rem_shm_page_addr = u->shm_page;
+ 
+              	shm_page->state &= ~BUSY_EXCLUSIVE;
+           	shm_page->state |= EXCLUSIVE;
+               	r.ret = 0;
+    	} else
+            	r.ret = 1;
+
+     	spin_unlock(&shm_page->shm_lock);
+ 
+	comm_free(u);
+        cli();
+        r.deputytime = current->mosix.deputytime;
+        current->mosix.deputytime = 0;
+        sti();
+        err = deputy_reply(REM_UPGRADE, &r, sizeof (r),NULL, 0, 0,2);
+
+	return err;
+} 
+int
  deputy_bring_page(struct bring_page_h *b)
  {
  	struct file *fp = b->fp;
  	struct vm_area_struct v;
-	struct page_ret_h r;
+	struct shm_page_ret_h r;
  	int err;
  	int address = b->offset;
  	struct page *page;
  	struct task_struct *p = current;
+	struct shm_page *shm_page=NULL;
+
+	struct vm_operations_struct file_vm_ops = {
+		nopage:  b->nopage,
+	};
+

  	v.vm_start = v.vm_pgoff = 0;
  	v.vm_end = address + PAGE_SIZE;
  	v.vm_mm = p->mm;	/* (eg. NULL) */
  	v.vm_file = fp;
-	v.vm_flags = 0;		/* anything really, but VM_SHARED */
+	v.vm_ops = &file_vm_ops;
+ 
+	v.vm_flags = (unsigned long)b->rem_shm_page_addr;

  	deeper_sleep();
-	page = b->nopage(&v, address, 0);
+
+	page =  get_nopage(&v, address, &shm_page, (b->access &
WITH_WRITE_ACC) ? 1 : 0);
+
  	lighter_sleep();
  	if (page == NOPAGE_OOM) {
  		r.ret = -ENOMEM;
-		page = 0;
-	} else
-		r.ret = page ? 0 : -EFBIG;
-	comm_free(b);
+		page = NULL;
+	} else if(page == PAGE_BUSY) {
+		page = NULL;
+		r.ret = -EBUSY;
+	}
+	else 
+		r.ret = (page ? 0 : -EINVAL);
+
+	if(page && (b->access & (WITH_WRITE_ACC|WITH_READ_ACC))) {
+
+		r.rem_shm_page_addr = shm_page;
+
+		if(b->access & WITH_WRITE_ACC ) {
+			if((!(v.vm_start)) && (!(v.vm_end))) {
+				r.next = 0;
+				r.next_addr = NULL;
+			} else {
+				r.next_addr = (struct shm_page *)v.vm_start;
+				r.next = v.vm_end;
+			}
+		} else	{
+			r.next = PE;
+			r.next_addr = shm_page;
+			r.prev = v.vm_end;
+                        r.prev_addr = (struct shm_page *)(v.vm_start);
+		}
+
+	}
+
  	cli();
  	r.deputytime = p->mosix.deputytime;
  	p->mosix.deputytime = 0;
@@ -942,13 +1032,77 @@
  	err = deputy_reply(REM_PAGE, &r, sizeof (r),
  			   page ? kmap(page) : NULL, page ? PAGE_SIZE : 0,
0,
  			   2);
-	if (page) {
-		kunmap(page);
-		__free_page(page);
+
+	if(shm_page) {
+		if(err) {
+			if(b->access & WITH_WRITE_ACC) {
+				spin_lock(&shm_page->shm_lock);
+				shm_page->state &= ~BUSY_EXCLUSIVE; 
+				if(!(v.vm_start) && !(v.vm_end)) {
+					shm_page->state |= EXCLUSIVE;
+					shm_page->owner = PE;
+					shm_page->prev = shm_page->next =
PE;
+					shm_page->next_addr =
shm_page->prev_addr = shm_page;
+					spin_unlock(&shm_page->shm_lock);
+					shm_pagecache_release(shm_page);
+				} else  {
+					shm_page->state |=
(SHARED|DROPPING);
+					spin_unlock(&shm_page->shm_lock);
+					shm_page->next = PE;
+					shm_page->next_addr = shm_page;
+
if(shm_send_message(shm_page->prev,shm_page,NULL,DROP_NEXT)) {
+						printk(KERN_ERR "reader loop
broken because of %d Reboot all\n",shm_page->prev); 
+						shm_page->owner =
shm_page->next = shm_page->prev = PE;
+                                                shm_page->next_addr =
shm_page->prev_addr = shm_page;
+
spin_lock(&shm_page->shm_lock);
+						shm_page->state &=
~(SHARED|DROPPING);
+						shm_page->state |=
EXCLUSIVE;
+
spin_unlock(&shm_page->shm_lock);
+
shm_pagecache_release(shm_page);
+						goto out;
+					}
+					shm_page->next = v.vm_end;
+					shm_page->next_addr = (struct
shm_page *)v.vm_start;
+					shm_page->state &= ~DROPPING;
+				} 
+			} else {
+                		spin_lock(&shm_page->shm_lock);
+				if(shm_page->next ==
current->mosix.whereami) {
+					shm_page->prev = shm_page->next =
PE;
+					shm_page->prev_addr =
shm_page->next_addr = shm_page;
+				} else {
+					shm_page->prev = v.vm_end;
+                                        shm_page->prev_addr = (struct
shm_page *)(v.vm_start);
+				}
+				shm_page->state &= ~DROPPING;
+				spin_unlock(&shm_page->shm_lock);
+			}
+		} else {
+			 if(b->access & WITH_WRITE_ACC) {
+                                spin_lock(&shm_page->shm_lock);
+				shm_page->state &= ~BUSY_EXCLUSIVE;
+				shm_page->state |= EXCLUSIVE;
+                              	shm_page->owner = current->mosix.whereami;
+				shm_page->rem_shm_page_addr =
b->rem_shm_page_addr;
+                               	shm_page->prev = shm_page->next =
PE;
+                               	shm_page->next_addr =
shm_page->prev_addr = shm_page; 
+                                spin_unlock(&shm_page->shm_lock);
+                        } 
+		} 
+	out:
+		shm_pagecache_release(shm_page);
  	}
+ 
+	comm_free(b);
+	if (page) {
+                kunmap(page);
+                __free_page(page);
+        }
  	return (err);
  }

+
+
  int
  deputy_tsc(void)
  {
@@ -1143,8 +1297,7 @@
  	if (deputy_request(DEP_EXEC_MMAP, NULL, 0, NULL, 0, 0,
  			   (void **) &r, -sizeof (r)))
  		return (-ENOMEM);
-	if (!r)
-		mosix_clear_all_held_files(current);
+
  	return (r);
  }

diff -Naur linux-2.4.26-om1/hpc/init.c linux-2.4.26-om1-o/hpc/init.c
--- linux-2.4.26-om1/hpc/init.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/init.c	2006-05-07 17:56:02.000000000 +0530
@@ -28,6 +28,30 @@
  void
  init_mosix(void)
  {
+	extern struct super_block bad_super_block;
+   	static struct super_operations empty_sops = {};
+ 	struct super_block *s = &bad_super_block;
+        if (s) {
+                memset(s, 0, sizeof(struct super_block));
+                INIT_LIST_HEAD(&s->s_dirty);
+                INIT_LIST_HEAD(&s->s_locked_inodes);
+                INIT_LIST_HEAD(&s->s_files);
+                INIT_LIST_HEAD(&s->s_instances);
+                init_rwsem(&s->s_umount);
+                sema_init(&s->s_lock, 1);
+                down_write(&s->s_umount);
+                s->s_count = S_BIAS;
+                atomic_set(&s->s_active, 1);
+                sema_init(&s->s_vfs_rename_sem,1);
+                sema_init(&s->s_nfsd_free_path_sem,1);
+                sema_init(&s->s_dquot.dqio_sem, 1);
+                sema_init(&s->s_dquot.dqoff_sem, 1);
+               	s->s_maxbytes = MAX_NON_LFS;
+              	s->s_op = &empty_sops;
+              	s->dq_op = NULL;
+                s->s_qcop = NULL;
+         }
+
  	extern int x86_udelay_tsc;
  	cpuspeed = ((int64_t) loops_per_jiffy) * STD_SPD / STD_LOOPS;
  	if (!x86_udelay_tsc)
@@ -43,4 +67,5 @@
  	mosinfo_update_gateways();
  	kernel_thread(mosix_info_daemon, NULL, 0);
  	kernel_thread(mosix_mem_daemon, NULL, 0);
+	kernel_thread(mosix_migshm_daemon,NULL,0);
  }
diff -Naur linux-2.4.26-om1/hpc/kernel.c linux-2.4.26-om1-o/hpc/kernel.c
--- linux-2.4.26-om1/hpc/kernel.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/kernel.c	2006-05-07 17:56:02.000000000 +0530
@@ -555,8 +555,6 @@
  		m->stay |= DSTAY_SYSTEM;
  	else
  		m->stay &= ~DSTAY_SYSTEM;
-	m->held_files = NULL;
-	m->held_allocated = 0;
  	rwlock_init(&m->state_lock);
  	m->contact = 0;
  	m->ucache = NULL;
@@ -597,7 +595,7 @@
  	init_waitqueue_head(mos_to_waitp(m));
  	m->mosix_log = NULL;
  	m->dirty_bits = 0;
-	return (fork_mosix_remote_files(p));
+	return 0;
  }

  void
@@ -729,63 +727,6 @@
  	m->pass_regs = 0;
  }

-void
-mosix_bring_monkey_users_back(struct inode *ip)
-{
-	struct task_struct *p, *found, *me = current;
-	DECLARE_WAITQUEUE(wait, me);
-
-	while (1) {
-		found = NULL;
-		read_lock(&tasklist_lock);
-		for_each_task(p)
-		    if (p != me && !(p->mosix.dflags & DREMOTE) &&
-			task_maps_ip(p, ip)) {
-			task_lock(p);
-			p->mosix.stay |= DSTAY_FOR_MONKEY;
-			task_unlock(p);
-			if (p->mosix.dflags & DDEPUTY) {
-				tell_process(p, DREQ_HOMEWAKE);
-				wake_up_mosix(p);
-				if (!found) {
-					found = p;
-					get_task_struct(p);
-				}
-			}
-		}
-		if (!found) {
-			read_unlock(&tasklist_lock);
-			/* VMODIFIED is needed against a nearly-impossible
-			 * REMOTE race, when ip is modified, then unmonkied
-			 * and a process migrates there even before the
-			 * previous completed exiting:
-			 */
-			OPENMOSIX_VMODIFIED(ip);
-			return;
-		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(mos_to_waitp(&found->mosix), &wait);
-		read_unlock(&tasklist_lock);
-		schedule();
-		remove_wait_queue(mos_to_waitp(&found->mosix), &wait);
-		set_current_state(TASK_RUNNING);
-		free_task_struct(found);
-	}
-}
-
-void
-mosix_no_longer_monkey(struct inode *ip)
-{
-	struct task_struct *p;
-
-	read_lock(&tasklist_lock);
-	for_each_task(p)
-	    if (!(p->mosix.dflags & (DREMOTE | DDEPUTY)) && task_maps_ip(p,
ip)) {
-		tell_process(p, DREQ_CHECKSTAY);
-		wake_up_mosix(p);
-	}
-	read_unlock(&tasklist_lock);
-}

  /*
   * caller is responsible to down_[read|write](&current->mm->mmap_sem)
@@ -824,8 +765,6 @@

  				ip = mpnt->vm_file->f_dentry->d_inode;
  				mode = ip->i_mode;
-				if (ip->i_mapping->i_mmap_shared)
-					stay |= DSTAY_FOR_MONKEY;
  				if (S_ISCHR(mode) || S_ISFIFO(mode) ||
  				    S_ISSOCK(mode))
  					stay |= DSTAY_FOR_DEV;
@@ -917,8 +856,6 @@
  {
  	if ((p->mosix.dflags & (DPASSING | DREMOTE)) == DPASSING)
  		return;
-	if (p->mosix.held_files)
-		mosix_clear_all_held_files(p);
  	if (!(p->mosix.dflags & DDEPUTY))
  		mosix_pre_dropping_mm(p, p->mm);
  	task_lock(p);
@@ -940,8 +877,6 @@
  	p->mosix.stay &= ~(DSTAY_PER_MM | DSTAY_FOR_CLONE);
  	task_unlock(p);
  	p->mosix.pages_i_bring = 0;
-	if (p->mosix.held_files)
-		mosix_clear_all_held_files(p);
  }

  int
diff -Naur linux-2.4.26-om1/hpc/Makefile linux-2.4.26-om1-o/hpc/Makefile
--- linux-2.4.26-om1/hpc/Makefile	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/Makefile	2006-05-07 17:56:02.000000000 +0530
@@ -20,7 +20,7 @@
  obj-y    := alternate.o auto_syscalls.o balance.o comm.o config.o decay.o
\
  	    deputy.o div.o export.o freemem.o init.o info.o kernel.o load.o
\
  	    mig.o hpcadmin.o hpcproc.o prequest.o remote.o rinode.o \
-	    service.o syscalls.o ucache.o badops.o
+	    service.o syscalls.o ucache.o badops.o mig_shm.o shm_comm.o
shm_filemap.o

  obj-$(CONFIG_MOSIX_DFSA) += dfsa.o

diff -Naur linux-2.4.26-om1/hpc/mig.c linux-2.4.26-om1-o/hpc/mig.c
--- linux-2.4.26-om1/hpc/mig.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/mig.c	2006-05-07 17:56:02.000000000 +0530
@@ -215,7 +215,9 @@
  	if (SHOW_MIGRATIONS)
  		printk("Weeeeeeeee.....\n");
  #endif /* SHOW_MIGRATIONS */
+
  	kickstart();
+
  	panic("kickstart returned");
         /*NOTREACHED*/ failed:
  	if (load_came_in) {
@@ -254,7 +256,6 @@
  {
  	struct task_struct *p = current;
  	int error;
-
  	if (!PE)
  		return (whereto && whereto != GOBACKHOME &&
  			whereto != MUSTGOHOME ? -EDIST : 0);
@@ -278,7 +279,7 @@
  		return (0);
  	}
  #endif /* CONFIG_MOSIX_CHEAT_MIGSELF */
-	if (whereto && ((p->mosix.stay & DSTAY) || !mos_to_net(whereto, 0)))
+	if (whereto && ((p->mosix.stay & DSTAY) || !mos_to_net(whereto, 0)))
  		return (-EDIST);

  	spin_lock_irq(&runqueue_lock);
@@ -477,9 +478,6 @@
  	int error;
  	int omigpages;

-	if (!p->mosix.held_files && (error = mosix_rebuild_file_list()))
-		return (error);
-
  	lock_mosix();
  	write_lock_irq(&tasklist_lock);
  	p->mosix.remote_caps = current->cap_effective;
@@ -500,7 +498,7 @@
  	unlock_mosix();
  	p->mosix.deputy_regs = ALL_REGISTERS;
  	p->mosix.pass_regs = 0;
-
+
  	if (!(mlink = comm_open(whereto, 0, comm_connect_timo))) {
  		error = -EDIST;
  		goto failed;
@@ -591,10 +589,6 @@
  #endif /*SHOW_MIGRATIONS */
  		end_coming_in(0);
  		current->mosix.pages_i_bring = 0;
-		if (p->mosix.dflags & DDELAYHELD) {
-			p->mosix.dflags &= ~DDELAYHELD;
-			mosix_rebuild_file_list();
-		}
  		return (0);
  	}

@@ -715,8 +709,6 @@
  		stop_storing_common_ps_info();
  		flush_read_cache();
  		free_ucache();
-		if (m->stay & DSTAY_FOR_MONKEY)
-			mosix_check_for_freedom_to_move();
  	} else {
  		if (m->contact) {
  			comm_close(m->contact);
@@ -772,6 +764,7 @@
  				m.uniq = ip->i_unique;
  				m.isize = ip->i_size;
  				m.nopage = vma->vm_ops->nopage;
+
  			}
  		} else {
  			m.fp = NULL;
@@ -962,9 +955,9 @@
  	comm_migration_mode(1);
  	neutralize_my_load(1);	/* don't count me: I'm going to disappear */
  	if (mig_send_mm_stats() || mig_send_mm_areas() ||
-	    (credit = mig_send_pages()) < 0 ||
-	    (current->used_math && mig_send_fp()) ||
-	    (current->mm->context.ldt && mig_send_ldt()) ||
+	   (credit = mig_send_pages()) < 0 ||
+	   (current->used_math && mig_send_fp()) ||
+	   (current->mm->context.ldt && mig_send_ldt()) ||
  	    mig_send_misc(credit)) {
  		comm_send(MIG_NOT_COMING, NULL, 0, NULL, 0, 0);
  		comm_migration_mode(0);
@@ -1000,6 +993,12 @@

  	/* unconvert prot+flags: */
  	flags = MAP_FIXED | MAP_PRIVATE;
+
+        if(m->flags & VM_SHARED) {
+                flags &= ~(MAP_PRIVATE);
+                flags|=MAP_SHARED;
+        }
+
  	prot = 0;
  	if (m->flags & VM_GROWSDOWN)
  		flags |= MAP_GROWSDOWN;
@@ -1481,7 +1480,6 @@
  	if (to > 0)
  		return (passto(to, 0) ?
  			(mos_to_net(to, NULL) ? -ENETUNREACH : -ENXIO) : 0);
-
  	switch (to) {
  	case DM_GOBACKHOME:
  		return (passto(GOBACKHOME, 0) ? -EDIST : 0);
diff -Naur linux-2.4.26-om1/hpc/mig_shm.c linux-2.4.26-om1-o/hpc/mig_shm.c
--- linux-2.4.26-om1/hpc/mig_shm.c	1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/mig_shm.c	2006-05-08 10:48:35.000000000 +0530
@@ -0,0 +1,744 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/locks.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/blkdev.h>
+#include <linux/file.h>
+#include <linux/swapctl.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/iobuf.h>
+#include<asm/system.h>
+ 
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/mman.h>
+ 
+#include <linux/highmem.h>
+#include<linux/vmalloc.h>
+
+
+#include<hpc/protocol.h>
+#include<hpc/mig_shm.h>
+#include<hpc/shm_pagemap.h>
+#include <linux/hpc.h>
+
+
+
+void invalidate(struct shm_page *shm_page,struct page *page,int
write_access)
+{
+ 
+	pte_t pte; 
+	pte_t *page_table;
+	unsigned long address;
+	struct vm_area_struct *vma;
+	struct mm_struct *mm;
+	struct address_space *mapping =  page->mapping;
+	struct task_struct *p = current;
+	int i=1;
+
+	lock_page(page);
+ 
+	spin_lock(&shm_page->shm_lock);
+
+	if(!(p->mosix.dflags & DDEPUTY) && !(p->mosix.dflags  & DREMOTE) &&
!(shm_page->state & AT_HOME)) {
+		if(write_access) {
+			shm_page->state &= ~STATE_MASK;
+			shm_page->state |= IDLE;
+		}
+		else {
+			shm_page->state &= ~STATE_MASK;
+			shm_page->state |= SHARED;
+		}
+	}
+
+	spin_unlock(&shm_page->shm_lock);
+ 
+        if((page->mapping == shm_page->mapping) && (page->index ==
shm_page->index)) {
+ 
+		spin_lock(&mapping->i_shared_lock);
+		vma = mapping->i_mmap_shared;
+
+		while(vma) {
+			if(page->index >= vma->vm_pgoff) {
+				address = ((page->index - vma->vm_pgoff) <<
PAGE_CACHE_SHIFT) + vma->vm_start;
+				if(address < vma->vm_end ) {
+					mm = vma->vm_mm;
+					spin_lock(&mm->page_table_lock);
+					page_table =
pte_offset(pmd_offset(pgd_offset(mm,address),address),address);
+					if(pte_present(*page_table) && (i ||
!pte_write(*page_table))) {
+         					flush_cache_page(vma,
address);
+         					pte =
ptep_get_and_clear(page_table);
+         					flush_tlb_page(vma,
address);
+
+ 						if(!write_access)
+
set_pte(page_table,pte_wrprotect(pte));
+						else {
+							mm->rss--;
+
page_cache_release(page);
+						}
+
+         					if (pte_dirty(pte))
+
set_page_dirty(page);
+					} 
+					spin_unlock(&mm->page_table_lock); 
+				}
+			}
+			vma = vma->vm_next_share; 
+			if(!vma && i--)
+				vma = mapping->i_mmap;
+		}
+ 
+		spin_unlock(&mapping->i_shared_lock);
+	}
+/*
+ * 	else 
+ *
+ *		printk("{trancated:%u %u}",page->mapping,page->index);
+ */
+
+ 
+	if(write_access && !(p->mosix.dflags & DREMOTE) && !(p->mosix.dflags
& DDEPUTY) && !(shm_page->state & AT_HOME)) {
+		page->shm_page = NULL;
+		shm_pagecache_release(shm_page);
+ 
+		ClearPageUptodate(page);
+		ClearPageDirty(page); 
+	}
+
+	unlock_page(page);
+	return;
+}
+ 
+
+static int send_upgrade(struct shm_page *shm_page,struct page *page)
+{
+	int res = 1;
+
+	lock_page(page);
+ 
+	if((shm_page->state & STATE_MASK) == SHARED)  {
+		res = remote_upgrade(shm_page);
+		if(!res) {
+			spin_lock(&shm_page->shm_lock);
+			shm_page->state &= ~SHARED;
+			shm_page->owner = PE;
+			shm_page->state |= EXCLUSIVE;
+			spin_unlock(&shm_page->shm_lock);
+		} else if(res == 2) {
+			shm_page->state |= PERM_ERR;
+			printk(KERN_ERR "A shared page here is invalid:
Reboot !\n");
+		}
+	} else if((shm_page->state & STATE_MASK) == EXCLUSIVE &&
((shm_page->owner == PE) || (shm_page->owner == 0))) 
+		res = 0;
+
+	unlock_page(page);
+	return res;
+}
+
+static struct page *get_exc_rem(struct vm_area_struct *vma,unsigned long
address,struct shm_page *shm_page)
+{
+	struct page *page;
+	int res = 0;
+ 
+        page = vma->vm_ops->nopage(vma,address,WITH_WRITE_ACC);
+
+	if(!page || (page == NOPAGE_OOM) || page == PAGE_BUSY)
+		return page;
+
+       	spin_lock(&shm_page->shm_lock);
+ 
+       	if(!(res = ((shm_page->state & STATE_MASK) == IDLE)) &&
((shm_page->state & STATE_MASK) == SHARED))  {
+		spin_unlock(&shm_page->shm_lock);
+         	res = send_upgrade(shm_page,page);
+		goto out;
+	}
+
+	spin_unlock(&shm_page->shm_lock);
+
+out:	if(!res)
+		return page;
+	else {
+		page_cache_release(page);
+		if(res == 1) 
+			return PAGE_BUSY;
+		else
+			return NULL;
+	}
+}
+
+ 
+static struct page *get_page_exc_in_exc(struct vm_area_struct *vma,
unsigned long address,struct shm_page *shm_page)
+{
+	struct page *page = NULL;
+
+	switch(current->mosix.dflags & (DDEPUTY|DREMOTE)) {
+ 
+		case DREMOTE :
+
+			spin_unlock(&shm_page->shm_lock);
+			page = get_exc_rem(vma,address,shm_page);
+
+			break;
+
+		case DDEPUTY:
+
+			if(!vma) goto  AS_HERE;
+
+			shm_page->state &= ~EXCLUSIVE;
+			shm_page->state |= BUSY_EXCLUSIVE;
+			spin_unlock(&shm_page->shm_lock);
+
+			if(!PE || (shm_page->owner == 0) || (shm_page->owner
== PE)) {
+				page = vma->vm_ops->nopage(vma,address,0);
+				if((page == NOPAGE_OOM )|| !page) {
+                                 	spin_lock(&shm_page->shm_lock);
+                                        shm_page->state &= ~BUSY_EXCLUSIVE;
+                                        shm_page->state |= EXCLUSIVE;
+                                        spin_unlock(&shm_page->shm_lock);
+                                        return page;
+                                }
+				invalidate(shm_page,page,1);
+				shm_pagecache_get(shm_page);
+			}  else {
+				page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+ 
+
if(shm_send_message(shm_page->owner,shm_page,page,FORWARD_REQUEST_WRITE)) 
+					goto here;
+
+				SetPageUptodate(page);
+				set_page_dirty(page);
+				unlock_page(page);
+			}
+
+			vma->vm_end = 0;
+                        vma->vm_start = 0;
+
+			break;
+
+		AS_HERE:
+		default:
+			if(!PE || (shm_page->owner == 0) || (shm_page->owner
== PE)) {
+				spin_unlock(&shm_page->shm_lock);
+				if(vma)
+					page = vma->vm_ops->nopage(vma,
address,0);
+			} else {
+ 
+				shm_page->state &= ~EXCLUSIVE;
+				shm_page->state |= BUSY_EXCLUSIVE;
+
+				spin_unlock(&shm_page->shm_lock);
+ 
+				page =
find_or_create_page(shm_page->mapping,
+
shm_page->index,GFP_NOFS);
+ 
+				shm_page->next = shm_page->prev = PE;
+                                shm_page->next_addr = shm_page->prev_addr =
shm_page;
+
+
+
if(shm_send_message(shm_page->owner,shm_page,page,FORWARD_REQUEST_WRITE)) {
+				here :  unlock_page(page);
+                                	page_cache_release(page);
+					printk(KERN_ERR "Data Loss : What
happened to node %d ,Reboot this node\n",shm_page->owner);
+                                        spin_lock(&shm_page->shm_lock);
+					shm_page->owner = PE;
+                                        shm_page->state &= ~BUSY_EXCLUSIVE;
+                                        shm_page->state |=
(EXCLUSIVE|PERM_ERR);
+                                        spin_unlock(&shm_page->shm_lock);
+					shm_pagecache_release(shm_page);
+                                        return NULL;
+                                } 
+
+				SetPageUptodate(page);
+				set_page_dirty(page);
+				unlock_page(page);
+
+				shm_page->owner = PE;
+ 
+				spin_lock(&shm_page->shm_lock);
+				shm_page->state |= EXCLUSIVE;
+				shm_page->state &= ~BUSY_EXCLUSIVE;
+				spin_unlock(&shm_page->shm_lock);
+
+				shm_pagecache_release(shm_page);
+			} 
+	}
+	return page;
+} 
+
+static struct page *get_page_exc_in_shared(struct vm_area_struct *vma,
unsigned long address,struct shm_page *shm_page)
+{
+	struct page *page = NULL;
+
+        switch(current->mosix.dflags & (DDEPUTY|DREMOTE)) {
+
+                case DREMOTE :
+
+                        spin_unlock(&shm_page->shm_lock);
+			page = get_exc_rem(vma,address,shm_page);
+
+                        break;
+
+                case DDEPUTY:
+ 
+			if(!vma) goto AS_HERE;
+
+			if(shm_page->state & DROPPING) {
+				page = PAGE_BUSY;
+				spin_unlock(&shm_page->shm_lock);
+			} else {
+				shm_page->state &= ~SHARED;
+				shm_page->state |= BUSY_EXCLUSIVE;
+
+				spin_unlock(&shm_page->shm_lock);
+ 
+ 
+				page = vma->vm_ops->nopage(vma,address,0);
+ 
+				if((page == NOPAGE_OOM) || !page) {
+                                     	spin_lock(&shm_page->shm_lock);
+                                       	shm_page->state &=
~BUSY_EXCLUSIVE;
+                                       	shm_page->state |= SHARED;
+
spin_unlock(&shm_page->shm_lock);
+                                       	return page;
+                                }
+ 
+				invalidate(shm_page,page,1); 
+ 
+
+				vma->vm_start = 0;
+                               	vma->vm_end = 0;
+
+				if(PE && (shm_page->prev != PE) &&
(shm_page->prev !=  0)) { 
+					vma->vm_end = shm_page->next;
+					vma->vm_start = (unsigned
long)shm_page->next_addr;
+					shm_page->next =
current->mosix.whereami;
+					shm_page->next_addr = (struct
shm_page *)vma->vm_flags;
+
if(shm_send_message(shm_page->prev,shm_page,page,DROP_NEXT)) {
+						printk("reader loop broken
because of %d ! reboot all",shm_page->prev);
+						shm_page->state |=
UPGRADE_ERR;
+					}
+				}
+			}
+
+                        break;
+
+		AS_HERE:
+                default:
+			if(shm_page->state & DROPPING) {
+				spin_unlock(&shm_page->shm_lock);
+				page = PAGE_BUSY;
+			} else {
+                        	shm_page->owner = PE;
+				shm_page->state |= DROPPING;
+                        	spin_unlock(&shm_page->shm_lock);
+ 
+				if(vma)
+                        		page =
vma->vm_ops->nopage(vma,address,0);
+ 
+				if(PE && (shm_page->next != PE) &&
(shm_page->next != 0)) 
+
if(shm_send_message(shm_page->next,shm_page,page,INVALIDATE))
+						shm_page->state |=
UPGRADE_ERR;
+
+				shm_page->next = shm_page->prev = PE;
+                                shm_page->next_addr = shm_page->prev_addr =
shm_page;
+
+				spin_lock(&shm_page->shm_lock);
+ 
+				shm_page->state &= ~SHARED;
+                        	shm_page->state |= EXCLUSIVE;
+				shm_page->state &= ~DROPPING;
+ 
+				spin_unlock(&shm_page->shm_lock);
+ 
+				shm_pagecache_release(shm_page);
+			}
+
+			break;
+
+        }
+        return page;
+}
+
+static struct page *get_page_shared_in_exc(struct vm_area_struct *vma,
unsigned long address,struct shm_page *shm_page)
+{
+	struct page *page = PAGE_BUSY;
+
+	switch(current->mosix.dflags & (DDEPUTY|DREMOTE)) {
+		case DREMOTE:
+ 
+			spin_unlock(&shm_page->shm_lock);
+			page =
vma->vm_ops->nopage(vma,address,WITH_READ_ACC);
+			break;
+
+		case DDEPUTY:
+ 
+			if(!vma) goto AS_HERE;
+
+			shm_page->prev = shm_page->next =
current->mosix.whereami;
+			shm_page->prev_addr = shm_page->next_addr = (struct
shm_page *)vma->vm_flags;
+
+			if(!PE || (shm_page->owner == 0) || (shm_page->owner
== PE)) {
+				shm_page->state &= ~EXCLUSIVE;
+				shm_page->state |= (SHARED|DROPPING);
+				spin_unlock(&shm_page->shm_lock);
+ 
+				page = vma->vm_ops->nopage(vma,address,0);
+				if((page == NOPAGE_OOM) || (!page))	{
+					spin_lock(&shm_page->shm_lock);
+					shm_page->state &=
~(SHARED|DROPPING);
+					shm_page->state |= EXCLUSIVE;
+					spin_unlock(&shm_page->shm_lock);
+					return page;
+				}
+ 
+                        	vma->vm_end = PE;
+                        	vma->vm_start =(unsigned long) shm_page;
+
+				invalidate(shm_page,page,0);
+				shm_pagecache_get(shm_page);
+			} else  {
+				shm_page->state &= ~EXCLUSIVE;
+                        	shm_page->state |= BUSY_SHARED;
+                        	spin_unlock(&shm_page->shm_lock);
+ 
+				vma->vm_end = shm_page->owner;
+				vma->vm_start = (unsigned
long)shm_page->rem_shm_page_addr;
+ 
+				shm_page->next = shm_page->owner;
+				shm_page->next_addr =
shm_page->rem_shm_page_addr;
+ 
+				page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+
+                               	if(shm_send_message(shm_page->owner,
shm_page,page, FORWARD_REQUEST_READ)) 
+					goto here;
+
+		      		SetPageUptodate(page);
+				set_page_dirty(page);
+				unlock_page(page);
+
+				spin_lock(&shm_page->shm_lock);
+				shm_page->state &= ~ BUSY_SHARED;
+				shm_page->state |= (SHARED|DROPPING);
+				spin_unlock(&shm_page->shm_lock);
+			}
+
+			break;
+
+		AS_HERE:
+		default:
+
+			if(!PE || (shm_page->owner == 0) || (shm_page->owner
== PE)) {
+				spin_unlock(&shm_page->shm_lock);
+				if(vma)
+					page =
vma->vm_ops->nopage(vma,address,0);
+			} else {
+				shm_page->state &= ~EXCLUSIVE;
+                                shm_page->state |= BUSY_SHARED;
+                                spin_unlock(&shm_page->shm_lock);
+
+                                shm_page->prev = shm_page->next =
shm_page->owner;
+                                shm_page->prev_addr = shm_page->next_addr
= shm_page->rem_shm_page_addr;
+
+				page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+ 
+
if(shm_send_message(shm_page->owner,shm_page,page,FORWARD_REQUEST_READ)) {
+				here:	unlock_page(page);
+					page_cache_release(page);
+					printk(KERN_INFO "Data Loss : What
happened to node %d ? Reboot this node\n",shm_page->owner);
+					shm_page->owner = PE;
+					spin_lock(&shm_page->shm_lock);
+					shm_page->state &= ~BUSY_SHARED;
+					shm_page->state |=
(EXCLUSIVE|PERM_ERR);
+					spin_unlock(&shm_page->shm_lock);
+					shm_pagecache_release(shm_page);
+					return NULL;
+				} 
+ 
+				SetPageUptodate(page);
+				set_page_dirty(page);
+				unlock_page(page);
+ 
+				spin_lock(&shm_page->shm_lock);
+				shm_page->state &= ~BUSY_SHARED;
+				shm_page->state |= SHARED;
+				spin_unlock(&shm_page->shm_lock);
+			}
+
+			break;
+	}
+	return page;
+}
+ 
+static struct page *get_page_shared_in_shared(struct vm_area_struct *vma,
unsigned long address,struct shm_page *shm_page)
+{
+	struct page *page = PAGE_BUSY;
+	struct task_struct *p = current;
+ 
+	if(p->mosix.dflags & DDEPUTY) {
+
+	 	if(shm_page->state & DROPPING)  {
+			spin_unlock(&shm_page->shm_lock);
+			return(page);
+		}
+
+		shm_page->state |= DROPPING;
+		spin_unlock(&shm_page->shm_lock);
+
+		page = vma->vm_ops->nopage(vma,address,0);
+		if((page == NOPAGE_OOM) || !page) {
+                        shm_page->state &= ~DROPPING;
+			return page;
+                }
+		if(PE && (shm_page->prev != PE) && (shm_page->prev != 0)) {
+
+			vma->vm_end   = shm_page->next;
+			vma->vm_start = (unsigned long)shm_page->next_addr;
+
+			shm_page->next =  p->mosix.whereami;
+			shm_page->next_addr = (struct shm_page
*)vma->vm_flags;
+
+
if(shm_send_message(shm_page->prev,shm_page,NULL,DROP_NEXT)) {
+				printk(KERN_ERR "node %d down:reader loop
broken,reboot all !\n",shm_page->prev); 
+				shm_page->next = vma->vm_end;
+				shm_page->next_addr = (struct shm_page
*)vma->vm_start;
+
+
shm_send_message(shm_page->next,shm_page,NULL,INVALIDATE);
+
+				shm_page->owner = shm_page->next =
shm_page->prev =PE;
+                                shm_page->next_addr = shm_page->prev_addr =
shm_page;
+
+				spin_lock(&shm_page->shm_lock);
+				shm_page->state &= ~(DROPPING|SHARED);
+				shm_page->state |= (EXCLUSIVE|UPGRADE_ERR);
+				spin_unlock(&shm_page->shm_lock);
+
+				page_cache_release(page);
+				shm_pagecache_release(shm_page);
+				return NULL;
+			}
+
+			shm_page->next =  vma->vm_end;
+                        shm_page->next_addr = (struct shm_page *)
vma->vm_start;
+
+			vma->vm_start = (unsigned long)shm_page->prev_addr;
+			vma->vm_end = shm_page->prev;
+
+		} else {
+			vma->vm_start = (unsigned long)shm_page;
+                        vma->vm_end = PE;
+                        shm_page->next_addr  = (struct shm_page
*)vma->vm_flags;
+                        shm_page->next = p->mosix.whereami;
+		}
+
+		shm_page->prev = current->mosix.whereami; 
+		shm_page->prev_addr = (struct shm_page *)vma->vm_flags;
+
+	} else { 
+ 
+		spin_unlock(&shm_page->shm_lock);
+		page = vma->vm_ops->nopage(vma,address,(p->mosix.dflags &
DREMOTE) ? WITH_READ_ACC:0);
+
+	}
+	return page;
+}
+
+
+
+
+static struct page *send_page_exclusive(struct vm_area_struct *vma,
unsigned long address,
+                                                        struct shm_page
*shm_page,int write_access)
+{
+        struct page *page = PAGE_BUSY;
+
+        spin_lock(&shm_page->shm_lock);
+
+	if((current->mosix.dflags & DDEPUTY) && (shm_page->writers ||
shm_page->readers)) {
+		spin_unlock(&shm_page->shm_lock);
+		goto out;
+	}
+
+        switch(shm_page->state & STATE_MASK) {
+
+                case  EXCLUSIVE:
+                case  IDLE: 
+			if((write_access == 11) && (!PE || ((shm_page->state
& STATE_MASK) == EXCLUSIVE))) {
+                                        spin_unlock(&shm_page->shm_lock);
+                                        return NULL;
+                        }
+ 
+                        page = get_page_exc_in_exc(vma, address, shm_page);
+
+                        break;
+
+                case  SHARED:
+                        page = get_page_exc_in_shared(vma, address,
shm_page);
+			break;
+                default:
+			spin_unlock(&shm_page->shm_lock);
+                        break;
+        }
+
+out:
+        return page;
+}
+
+static struct page *send_page_shared(struct vm_area_struct *vma,unsigned
long address,struct shm_page *shm_page)
+{
+        struct page *page = PAGE_BUSY;
+
+        spin_lock(&shm_page->shm_lock);
+	if((current->mosix.dflags & DDEPUTY) && ((shm_page->writers) ||
(shm_page->state & UPGRADE_ERR)) ) {
+		if(shm_page->state & UPGRADE_ERR)
+			page = NULL;
+		spin_unlock(&shm_page->shm_lock);
+		goto out;
+	} 
+
+        switch(shm_page->state & STATE_MASK) {
+
+                case EXCLUSIVE:
+                case IDLE:
+ 
+			page = get_page_shared_in_exc(vma,address,shm_page);
+
+                        break;
+                case SHARED:
+                        page =
get_page_shared_in_shared(vma,address,shm_page);
+			break;
+                default:
+			spin_unlock(&shm_page->shm_lock);
+                        break;
+        }
+
+out: 
+        return page;
+}
+
+void wait_here() 
+{
+	current->state = TASK_INTERRUPTIBLE;
+      	schedule_timeout(5*HZ);
+}
+ 
+struct page *get_nopage(struct vm_area_struct *vma, unsigned long
address,struct shm_page **shm_page,int write_access)
+{
+        struct page *new_page = NULL;
+        struct task_struct *p = current;
+        struct address_space *mapping =
vma->vm_file->f_dentry->d_inode->i_mapping;
+        unsigned long index = ((address - vma->vm_start) >>
PAGE_CACHE_SHIFT) + vma->vm_pgoff;
+
+        *shm_page = find_or_create_shm_page(mapping,index);
+	if((*shm_page)->state & PERM_ERR) 
+		goto out;
+
+        while(1) {
+                if((write_access == 1) || (write_access == 11))
+                        new_page=send_page_exclusive(vma, address &
PAGE_MASK, *shm_page, write_access);
+                else if(write_access == 0 || write_access == 2) 
+                        new_page=send_page_shared(vma, address & PAGE_MASK,
*shm_page);
+
+                if((new_page != PAGE_BUSY) || (p->mosix.dflags & DDEPUTY))
+                        break;
+		else
+			wait_here();
+        }
+
+out:	if((new_page == NULL || new_page == NOPAGE_OOM || new_page ==
PAGE_BUSY || (write_access == 2)) && write_access != 11) {
+		shm_pagecache_release(*shm_page);
+		*shm_page = NULL;
+	}
+
+        return new_page;
+}
+
+int
+get_pages(struct address_space *mapping,loff_t offset,size_t count,int
writer)
+{
+	struct shm_page *shm_page;
+	struct page *page=NULL;
+	unsigned long 	index = (offset >> PAGE_CACHE_SHIFT),
+			end = ((offset+count) >> PAGE_CACHE_SHIFT);
+ 
+	for(;index <= end; index++) {
+
+		shm_page = find_or_create_shm_page(mapping,index);
+
+		if(shm_page->state & PERM_ERR)
+			return (index + 1); 
+
+		spin_lock(&shm_page->shm_lock);
+ 
+		if(writer)
+			shm_page->writers++;
+		else
+			shm_page->readers++;
+ 
+ 
+	again:	switch(shm_page->state & STATE_MASK) { 
+			case EXCLUSIVE:
+				if(PE && (shm_page->owner != PE) &&
(shm_page->owner != 0)) {
+					if(writer) {
+						if(shm_page->readers)  {
+							page = PAGE_BUSY;
+
spin_unlock(&shm_page->shm_lock);
+						}
+						else
+							page =
get_page_exc_in_exc(NULL,0,shm_page);
+					} else
+						page =
get_page_shared_in_exc(NULL,0,shm_page);
+
+					if(page ==  PAGE_BUSY) 
+						goto here;
+				 	else if (page)
+						page_cache_release(page);
+				} else
+					spin_unlock(&shm_page->shm_lock);
+				break;
+
+			case SHARED:
+				if(!writer) {
+					spin_unlock(&shm_page->shm_lock);
+					break;
+				} else
if(!get_page_exc_in_shared(NULL,0,shm_page)) {
+						break;
+				} else 
+					goto here;
+			default:
+				spin_unlock(&shm_page->shm_lock);
+			here:	wait_here();
+				spin_lock(&shm_page->shm_lock);
+				goto again;
+		}
+	}
+	return 0;
+}
+void 
+put_pages(struct address_space *mapping,loff_t offset,size_t count,int
writer,unsigned long end) 
+{
+
+	struct shm_page *shm_page;
+	unsigned long index = (offset >> PAGE_CACHE_SHIFT);
+ 
+	if(!end--) 
+            	end = ((offset+count) >> PAGE_CACHE_SHIFT);
+
+	for(;index <= end; index++) {
+		shm_page =
find_get_shm_page(mapping,index,shm_page_hash(mapping,index));
+ 
+		spin_lock(&shm_page->shm_lock);
+		if(writer) 
+			shm_page->writers--;
+		else
+			shm_page->readers--;
+		spin_unlock(&shm_page->shm_lock);
+ 
+		shm_pagecache_release(shm_page);
+		shm_pagecache_release(shm_page);
+	}
+}
+ 
diff -Naur linux-2.4.26-om1/hpc/remote.c linux-2.4.26-om1-o/hpc/remote.c
--- linux-2.4.26-om1/hpc/remote.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/remote.c	2006-05-07 17:56:02.000000000 +0530
@@ -31,6 +31,8 @@
  #include <linux/file.h>
  #include <hpc/balance.h>
  #include <hpc/dfsa.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>

  int
  remote_wait(int expect, void **head, int *hlen)
@@ -109,10 +111,6 @@
  			    remote_mprotect((struct mprotect_parameters_h *)
  					    *head);
  			break;
-		case DEP_LISTHOLD:
-			comm_free(*head);
-			error = remote_report_files();
-			break;
  		case DEP_SETUPFRAME:
  			error =
  			    remote_setup_frame((struct
setupframe_parameters_h
@@ -471,22 +469,93 @@
  	bump_syscalls();	/* no accurate numbers, but it costs! */
  	wait_for_permission_to_continue();
  }
+int
+remote_writepage(struct page *page)
+{
+	struct shm_page *shm_page;
+	int res;
+	shm_page = page->shm_page;
+
+	struct address_space *mapping = page->mapping;
+	unsigned long index = page->index;
+
+retry:	if((shm_page->state & STATE_MASK) == IDLE)
+		goto out;
+
+	if((shm_page->state & STATE_MASK) == EXCLUSIVE) 
+		res =
shm_send_message(page->mapping->host->u.remote_i.origin,shm_page,page,WRITE_
BACK);
+	else 
+		res =
shm_send_message(page->mapping->host->u.remote_i.origin,shm_page,page,DROP_P
AGE);
+
+	if(res == 1) { 
+		SetPageDirty(page); 
+		unlock_page(page);
+		wait_here();
+		lock_page(page);
+		if(mapping != page->mapping || index != page->index) 
+			goto out;
+
+		goto retry;
+	} else  {
+		ClearPageDirty(page);
+		if(res)
+			printk(KERN_ERR "Comm loss: Reboot this and %d %d
nodes !\n",shm_page->next,shm_page->prev);
+
+		spin_lock(&shm_page->shm_lock);
+		shm_page->state &= ~STATE_MASK;
+		shm_page->state  |= IDLE; 
+		spin_unlock(&shm_page->shm_lock);
+
+		page->shm_page =  NULL;
+		shm_pagecache_release(shm_page);
+	}
+
+out:	unlock_page(page); 
+	return(0);
+}
+
+int 
+remote_upgrade(struct shm_page *shm_page)
+{
+	struct upgrade_h u;
+	struct shm_page_ret_h r;
+
+	u.rem_shm_page_addr = shm_page->rem_shm_page_addr;
+	u.shm_page = shm_page;
+	int error;
+
+	if (!(error = remote_request(REM_UPGRADE, &u, sizeof (u), NULL, 0,
0,
+                                          (void **) &r, -sizeof (r))))  {
+		if((!(r.ret)) && (shm_page->prev != 0) && (shm_page->prev !=
PE)) 
+
shm_send_message(shm_page->next,shm_page,NULL,INVALIDATE);
+		error =  r.ret;
+	}
+
+	absorb_deptime(r.deputytime);

+	return error;
+}
+
  int
  remote_readpage(struct file *fp, struct page *page)
  {
-	int error;
+	int error=0;
  	char *buffer = kmap(page);
  	struct bring_page_h b;
-	struct page_ret_h r;
+	struct shm_page_ret_h r;
  	int dpagein = (current->mosix.dflags & DPAGEIN) ^ DPAGEIN;
  	struct task_struct *p = current;
-
+	struct shm_page *shm_page = page->shm_page;
+
  	if (!PageLocked(page))
  		PAGE_BUG(page);
+
  	b.fp = home_file(fp);
-	b.offset = page->index << PAGE_CACHE_SHIFT;
+	b.offset = (page->index << PAGE_CACHE_SHIFT);
  	b.nopage = fp->f_dentry->d_inode->u.remote_i.nopage;
+	b.rem_shm_page_addr = shm_page; 
+	b.access = (shm_page->state & ACC_MASK);
+
  	if (p->mosix.rfreepages > 0)
  		p->mosix.rfreepages--;
  	else
@@ -498,28 +567,65 @@
  		p->mosix.dflags |= dpagein;
  		spin_unlock_irq(&runqueue_lock);
  	}
-	if (!b.nopage)		/* home rebooted, we should be dead anyway
*/
-		error = -EIO;
+ 
+	if (!b.nopage)	   /* home rebooted, we should be dead anyway */
+		error = -EIO;
  	else if (!(error = remote_request(REM_PAGE, &b, sizeof (b), NULL, 0,
0,
-					  (void **) &r, -sizeof (r))))
+					  (void **) &r, -sizeof (r))))
  		error = r.ret;
-	if (!error)
+
+	if (!error)
  		error = comm_copydata(buffer, PAGE_SIZE, 0);
-	else if (error == -EFBIG) {
-		memset(buffer, 0, PAGE_SIZE);
-		error = 0;
-	}
-	if (error) {
+
+	if(!error) {
+ 
+		spin_lock(&shm_page->shm_lock);
+
+		shm_page->owner = PE;
+
+		shm_page->state &= ~STATE_MASK;
+		shm_page->state |= ((b.access & WITH_WRITE_ACC) ? EXCLUSIVE
: SHARED);
+
+		spin_unlock(&shm_page->shm_lock);
+
+		shm_page->rem_shm_page_addr = r.rem_shm_page_addr;
+
+		shm_page->next = r.next;
+		shm_page->next_addr = r.next_addr;
+
+		if(b.access & WITH_WRITE_ACC) {
+			if(r.next_addr) 
+
if(shm_send_message(shm_page->next,shm_page,page,INVALIDATE))
+					printk(KERN_ERR "REBOOT ALL\n");
+			shm_page->next_addr = shm_page->prev_addr =
shm_page;
+			shm_page->next = shm_page->prev = PE;
+ 
+		} else {
+			shm_page->prev = r.prev;
+			shm_page->prev_addr = r.prev_addr;
+
shm_send_message(current->mosix.deppe,shm_page,NULL,DROP_PAGE_END);
+		}
+
+                SetPageUptodate(page);
+		set_page_dirty(page);
+	} else {
+
  		ClearPageUptodate(page);
-		SetPageError(page);
-	} else
-		SetPageUptodate(page);
+		ClearPageDirty(page);
+                SetPageError(page);
+		page->shm_page =  NULL;
+		shm_pagecache_release(shm_page);
+	}
+
+	shm_page->state &= ~ACC_MASK;
+
  	UnlockPage(page);
  	kunmap(page);
  	spin_lock_irq(&runqueue_lock);
  	p->mosix.dflags &= ~dpagein;
  	spin_unlock_irq(&runqueue_lock);
  	absorb_deptime(r.deputytime);
+
  	return (error);
  }

@@ -658,28 +764,34 @@
  		}
  	} else
  		rf = NULL;
-	/* unconvert prot+flags: */
-	prot = 0;
-	flags = MAP_PRIVATE;
-	if (m->fixed)
-		flags |= MAP_FIXED;
-	if (m->flags & VM_GROWSDOWN)
-		flags |= MAP_GROWSDOWN;
-	if (m->flags & VM_DENYWRITE)
-		flags |= MAP_DENYWRITE;
-	if (m->flags & VM_EXECUTABLE)
-		flags |= MAP_EXECUTABLE;
-	if (m->flags & VM_READ)
-		prot |= VM_READ;
-	if (m->flags & VM_WRITE)
-		prot |= VM_WRITE;
-	if (m->flags & VM_EXEC)
-		prot |= VM_EXEC;
+	 prot = 0;
+	 flags = MAP_PRIVATE;
+	if(m->flags & VM_SHARED) {
+		flags &= ~(MAP_PRIVATE);
+		flags|=MAP_SHARED;
+	} 
+      	if (m->fixed)
+              	flags |= MAP_FIXED;
+      	if (m->flags & VM_GROWSDOWN)
+              	flags |= MAP_GROWSDOWN;
+      	if (m->flags & VM_DENYWRITE)
+     		flags |= MAP_DENYWRITE;
+     	if (m->flags & VM_EXECUTABLE)
+              	flags |= MAP_EXECUTABLE;
+      	if (m->flags & VM_READ)
+              	prot |= PROT_READ;
+      	if (m->flags & VM_WRITE)
+              	prot |= PROT_WRITE;
+      	if (m->flags & VM_EXEC)
+              	prot |= PROT_EXEC;
+
  	if (m->flags & VM_MAYSHARE)
  		current->mosix.dirty_bits |= MMAP_MAYSHARE;
+
  	result = do_mmap_pgoff(rf, m->addr, m->len, prot, flags, m->pgoff);
+
  	if (m->flags & VM_MAYSHARE)
-		current->mosix.dirty_bits &= ~MMAP_MAYSHARE;
+ 		current->mosix.dirty_bits &= ~MMAP_MAYSHARE;
  	if (rf && !IS_ERR((const void *) result)) {
  		int pages = (m->len + PAGE_SIZE - 1) / PAGE_SIZE;

@@ -688,8 +800,9 @@
  			current->mosix.rfreepages += pages;
  	}
  	if (m->flags & VM_READHINTMASK)
-		sys_madvise(m->addr, m->len, (m->flags & VM_SEQ_READ) ?
-			    MADV_RANDOM : MADV_SEQUENTIAL);
+               sys_madvise(m->addr, m->len, (m->flags & VM_SEQ_READ) ?
+                           MADV_RANDOM : MADV_SEQUENTIAL);
+
        err:
  	if (rf)
  		fput(rf);
diff -Naur linux-2.4.26-om1/hpc/rinode.c linux-2.4.26-om1-o/hpc/rinode.c
--- linux-2.4.26-om1/hpc/rinode.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/rinode.c	2006-05-07 17:56:02.000000000 +0530
@@ -10,14 +10,16 @@
  #include <hpc/protocol.h>
  #include <hpc/comm.h>
  #include <linux/hpc.h>
+#include <linux/locks.h>
  #include <linux/smp_lock.h>
  #include <linux/file.h>
  #include <linux/dcache.h>
  #include <linux/slab.h>
  #include <hpc/routines.h>
  #include <hpc/debug.h>
-
+#include <hpc/mig_shm.h>
  /* REMOTE section: */
+//extern int remote_writepage(struct file*,struct page*);

  spinlock_t rinode_list_lock = SPIN_LOCK_UNLOCKED;

@@ -33,7 +35,6 @@

  static struct dentry_operations remote_dentry_ops = {
  	.d_delete = remote_dentry_delete,
-	.d_iput = remote_dentry_iput
  };

  static struct file_operations remote_file_operations = {
@@ -41,19 +42,21 @@
  };

  struct address_space_operations remote_aops = {
+	.writepage = remote_writepage,
  	.readpage = remote_readpage,
  };

-void
-invalidate_old_remote_pages(struct inode *ip)
+
+static
+struct inode *hpc_new_inode(struct super_block *sb)
  {
-	down(&ip->i_sem);
-	/* we prefer "invalidate_inode_pages",
-	   but it does not work on locked pages */
-	truncate_inode_pages(ip->i_mapping, 0);
-	up(&ip->i_sem);
+       	struct inode *inode = new_inode(sb);
+	if(inode)
+		insert_inode_hash(inode);
+	return (inode);
  }

+
  struct file *
  get_remote_file(int origin, struct file *fpr, struct dentry *dpr, uint64_t
uniq,
  		off_t isize, nopage_t nopage)
@@ -80,6 +83,7 @@
  		}
  	if (!(f = get_empty_filp()))
  		return (NULL);
+
  	spin_lock(&dcache_lock);
  	spin_lock(&rinode_list_lock);
  	for (d = rinode_list; d; d = next_entry(d)) {
@@ -99,23 +103,29 @@
  			spin_unlock(&dcache_lock);
  			if (to_iput)
  				iput(to_iput);
+
  			if (to_dput)
  				dput(to_dput);
-			if (cng)
-				invalidate_old_remote_pages(ip);
+
  			f->f_dentry = d;
  			f->f_op = &remote_file_operations;
-			f->f_mode = FMODE_READ;
+			f->f_mode = FMODE_READ|FMODE_WRITE;
  			home_file(f) = fpr;
+
+			shm_send_message(current->mosix.deppe,(struct
shm_page *)fpr,NULL,GET_FILE);
+
  			return (f);
  		}
  	}
  	spin_unlock(&rinode_list_lock);
  	spin_unlock(&dcache_lock);
-	if (!(ip = new_inode(&bad_super_block))) {
+
+	if (!(ip = hpc_new_inode(&bad_super_block))) {
  		put_filp(f);
  		return (NULL);
  	}
+
+
  	ip->i_mode = S_IFREG;
  	ip->u.remote_i.origin = origin;
  	ip->u.remote_i.dp = dpr;
@@ -124,8 +134,9 @@
  	ip->i_size = isize;
  	ip->i_fop = &remote_file_operations;
  	ip->i_mapping->a_ops = &remote_aops;
-	if (!(d = d_alloc(NULL, &(const struct qstr) {
-			  "/", 1, 0}))) {
+	if (!(d = d_alloc(NULL, &(const struct qstr)  {
+			  "/", 1, 0 } ))) {
+
  		put_filp(f);
  		iput(ip);
  		return (NULL);
@@ -150,10 +161,11 @@
  	rinode_list = d;
  	f->f_dentry = d;
  	f->f_op = &remote_file_operations;
-	f->f_mode = 1;
+	f->f_mode = FMODE_READ|FMODE_WRITE;
  	home_file(f) = fpr;
  	spin_unlock(&rinode_list_lock);
  	spin_unlock(&dcache_lock);
+	shm_send_message(current->mosix.deppe,(struct shm_page
*)fpr,NULL,GET_FILE);
  	return (f);
  }

@@ -179,14 +191,7 @@
  	spin_unlock(&rinode_list_lock);
  	return (1);
  }
-
-static void
-remote_dentry_iput(struct dentry *dp, struct inode *ip)
-{
-	invalidate_old_remote_pages(ip);
-	iput(ip);
-}
-
+
  struct vm_operations_struct rinode_mmap = {
  	.nopage = filemap_nopage,
  };
@@ -194,393 +199,6 @@
  static int
  mosix_remote_file_mmap(struct file *file, struct vm_area_struct *vma)
  {
-	if (vma->vm_flags & VM_SHARED)
-		panic("REMOTE VM_SHARED mmap");
  	vma->vm_ops = &rinode_mmap;
  	return (0);
  }
-
-int
-remote_report_files(void)
-{
-	struct vm_area_struct *vma, *vmb;
-	struct mm_struct *mm = current->mm;
-	struct file **fp = NULL;
-	int n = 0;
-	int result;
-
-	down_read(&mm->mmap_sem);
-	for (vma = mm->mmap; vma; vma = vma->vm_next)
-		if (vma->vm_file) {
-			for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next)
-				if (vmb->vm_file == vma->vm_file)
-					break;
-			if (vmb == vma)
-				n++;
-		}
-	up_read(&mm->mmap_sem);
-	if (n && !(fp = kmalloc(n * sizeof (struct file *), GFP_KERNEL)))
-		n = -EAGAIN;
-	else {
-		down_read(&mm->mmap_sem);
-		for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next)
-			if (vma->vm_file) {
-				for (vmb = mm->mmap; vmb != vma;
-				     vmb = vmb->vm_next)
-					if (vmb->vm_file == vma->vm_file)
-						break;
-				if (vmb == vma)
-					fp[n++] = home_file(vma->vm_file);
-			}
-		up_read(&mm->mmap_sem);
-	}
-	result = comm_send(DEP_LISTHOLD | REPLY, &n, sizeof (int),
-			   fp, n > 0 ? n * sizeof (struct file *) : 0, 0);
-	if (n > 0)
-		kfree(fp);
-	return (result);
-}
-
-void
-rinode_flush_files(int pe)
-{
-	struct dentry *dp;
-	struct inode *ip;
-
-      loop:
-	spin_lock(&rinode_list_lock);
-	for (dp = rinode_list; dp; dp = next_entry(dp)) {
-		ip = dp->d_inode;
-		if (ip->u.remote_i.origin == pe && ip->u.remote_i.nopage) {
-			ip->u.remote_i.dp = NULL;
-			/* (the pointer is no good and any process
-			 * still using this inode is doomed anyway) */
-			ip->u.remote_i.unique = 0xffffffffffffffffULL;
-			ip->u.remote_i.nopage = NULL;
-			spin_unlock(&rinode_list_lock);
-			invalidate_old_remote_pages(ip);
-			goto loop;
-		}
-	}
-	spin_unlock(&rinode_list_lock);
-}
-
-/* DEPUTY section: */
-
-#define DEFAULT_ALLOCATION	10
-
-#define	ALLOCATED_NEW		1
-#define	ALLOCATED_NEW_AND_DENY	2
-#define	ADDED_A_DENY		3
-#define	FOUND_OLD		4
-
-int
-mosix_register_a_file(struct file *fp, int denywrite)
-{
-	struct task_struct *p = current;
-	int i, new;
-	struct held_files *nh, *oh;
-	struct mm_struct *mm;
-
-	if (!p->mosix.held_allocated) {
-		if ((mm = p->mm) && atomic_read(&mm->mm_realusers) > 1)
-			return (0);
-		nh = NULL;	/* COMPILER BUG -- hope it is optimized out
*/
-		for (i = DEFAULT_ALLOCATION; i > 0; i >>= 1)
-			if ((nh = (struct held_files *)
-			     kmalloc(i * sizeof (struct held_files),
-				     GFP_KERNEL)))
-				break;
-		if (!nh)
-			return (-ENOMEM);
-		memset(nh, 0, i * sizeof (struct held_files));
-		task_lock(p);
-		p->mosix.held_files = nh;
-		p->mosix.held_allocated = i;
-		task_unlock(p);
-		new = 0;
-	} else {
-		new = -1;
-		for (i = 0; i < p->mosix.held_allocated; i++)
-			if ((struct file *) p->mosix.held_files[i].f == fp)
{
-				if (!denywrite
-				    || p->mosix.held_files[i].denywrite)
-					return (FOUND_OLD);
-				if (deny_write_access(fp))
-					return (-ETXTBSY);
-				p->mosix.held_files[i].denywrite = 1;
-				return (ADDED_A_DENY);
-			} else if (new == -1 && !p->mosix.held_files[i].f)
-				new = i;
-		if (new == -1) {
-			nh = NULL;	/* COMPILER BUG -- hope it is
optimized out */
-			for (i = DEFAULT_ALLOCATION; i > 0; i >>= 1)
-				if ((nh =
-				     kmalloc((i +
-					      p->mosix.held_allocated) *
-					     sizeof (struct held_files),
-					     GFP_KERNEL)))
-					break;
-			if (!i)
-				return (-ENOMEM);
-			for (new = p->mosix.held_allocated + i - 1;
-			     new >= p->mosix.held_allocated; new--)
-				nh[new].f = NULL;
-			for (new = 0; new < p->mosix.held_allocated; new++)
-				nh[new] = p->mosix.held_files[new];
-			oh = p->mosix.held_files;
-			task_lock(p);
-			p->mosix.held_files = nh;
-			p->mosix.held_allocated += i;
-			task_unlock(p);
-			kfree(oh);
-		}
-	}
-	get_file(fp);
-	task_lock(p);
-	p->mosix.held_files[new].f = fp;
-	task_unlock(p);
-	if ((p->mosix.held_files[new].denywrite = denywrite)) {
-		if (deny_write_access(fp)) {
-			task_lock(p);
-			p->mosix.held_files[new].f = NULL;
-			task_unlock(p);
-			return (-ETXTBSY);
-		}
-		return (ALLOCATED_NEW_AND_DENY);
-	} else
-		return (ALLOCATED_NEW);
-}
-
-void
-mosix_undo_last_file_registration(struct file *fp, int result)
-{
-	unsigned int i;
-	struct mosix_task *m = &current->mosix;
-
-	if (result == FOUND_OLD)
-		return;
-	for (i = 0; i < m->held_allocated; i++)
-		if ((struct file *) m->held_files[i].f == fp) {
-			switch (result) {
-			case ADDED_A_DENY:
-			case ALLOCATED_NEW_AND_DENY:
-				if (!m->held_files[i].denywrite)
-					printk
-					    ("%s:
mosix_undo_last_file_registration - no denywrite\n",
-					     desc_mostask(m));
-				else
-					allow_write_access(fp);
-				if (result == ADDED_A_DENY)
-					break;
-			case ALLOCATED_NEW:
-				fput(fp);
-				task_lock(current);
-				m->held_files[i].f = NULL;
-				task_unlock(current);
-				break;
-			}
-			return;
-		}
-	printk("%s: mosix_undo_last_file_registration - not found\n",
-	       desc_mostask(m));
-}
-
-void
-mosix_update_remote_files(void)
-{
-	struct task_struct *p = current;
-	struct held_files *h = p->mosix.held_files;
-	unsigned int i, j;
-	int op, np;
-	struct file **rf;
-	struct file *fp;
-
-	if (!(op = p->mosix.held_allocated))
-		return;
-	if (deputy_request(DEP_LISTHOLD, NULL, 0, NULL, 0, 0,
-			   (void **) &np, -sizeof (int)))
-		deputy_die_on_communication();
-	if (np < 0 || (np && comm_recvdata((void **) &rf) < 0))
-		deputy_die_on_communication();
-	for (j = 0; j < op; j++)
-		h[j].denywrite = (h[j].denywrite != 0) | 2;
-	for (i = 0; i < np; i++) {
-		for (j = 0; j < op; j++)
-			if (h[j].f == rf[i]) {
-				h[j].denywrite &= ~2;
-				break;
-			}
-		if (j == op)
-			panic("mosix_update_remote_files: not listed");
-	}
-	for (j = 0; j < op; j++)
-		if ((fp = h[j].f) && (h[j].denywrite & 2)) {
-			task_lock(p);
-			h[j].f = NULL;
-			task_unlock(p);
-			if (h[j].denywrite & 1)
-				allow_write_access(fp);
-			fput(fp);
-		}
-	if (np)
-		comm_free(rf);
-}
-
-int
-mosix_rebuild_file_list(void)
-{
-	struct task_struct *p = current;
-	struct vm_area_struct *vma, *vmb;
-	struct mm_struct *mm = p->mm;
-	struct held_files *hf = NULL, *old;
-	unsigned int i, n;
-	int oldn;
-	unsigned int denywrite;
-	struct file *this;
-
-	if (p->mosix.dflags & DDEPUTY) {
-		if (p->mosix.dflags & DINCOMING)
-			p->mosix.dflags |= DDELAYHELD;
-		else
-			mosix_update_remote_files();
-		return (0);
-	}
-	if (atomic_read(&mm->mm_realusers) > 1) {
-		mosix_clear_all_held_files(p);	/* discard old */
-		return (-EBUSY);	/* thread */
-	}
-	/* because we are the only clone, no MM lock is needed */
-	/* and the initial count cannot change */
-
-	for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next)
-		if ((this = vma->vm_file)) {
-			for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next)
-				if (vmb->vm_file == vma->vm_file)
-					break;
-			if (vmb == vma) {
-				if (this->f_dentry->d_inode->i_mapping->
-				    i_mmap_shared) {
-				      monkey:
-					mosix_clear_all_held_files(p);
-					tell_process(p, DREQ_CHECKSTAY);
-					return (-EDIST);
-				}
-				n++;
-			}
-		}
-	if (n && !(hf = kmalloc(n * sizeof (struct held_files),
GFP_KERNEL))) {
-		mosix_clear_all_held_files(p);	/* discard old */
-		return (-ENOMEM);
-	}
-	for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next)
-		if ((this = vma->vm_file)) {
-			for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next)
-				if (vmb->vm_file == this)
-					goto already_placed;
-			denywrite = 0;
-			for (; vmb; vmb = vmb->vm_next)
-				if (vmb->vm_file == this
-				    && (vmb->vm_flags & VM_DENYWRITE)) {
-					denywrite = 1;
-
atomic_dec(&this->f_dentry->d_inode->
-						   i_writecount);
-					break;
-				}
-			get_file(this);
-			hf[n].f = this;
-			hf[n++].denywrite = denywrite;
-		      already_placed:;
-		}
-	/* must not use "mosix_clear_all_held_files" because it could sleep
*/
-	/* in 'fput' when another held file becomes VMONKEY */
-	oldn = p->mosix.held_allocated;
-	old = p->mosix.held_files;
-	task_lock(p);
-	p->mosix.held_files = hf;
-	p->mosix.held_allocated = n;
-	task_unlock(p);
-	if (old) {
-		for (i = 0; i < oldn; i++)
-			if ((this = old[i].f)) {
-				if (old[i].denywrite)
-					allow_write_access(this);
-				fput(this);
-			}
-		kfree(old);
-	}
-	/* final race check: has any file been made monkey meanwhile? */
-	for (i = 0; i < n; i++)
-		if (hf[i].f->f_dentry->d_inode->i_mapping->i_mmap_shared)
-			goto monkey;
-	return (0);
-}
-
-int
-fork_mosix_remote_files(struct task_struct *p)
-{
-	unsigned int i;
-	struct file *fp;
-
-	if (!(p->mosix.held_allocated = current->mosix.held_allocated))
-		return (0);
-	if (!(p->mosix.held_files = kmalloc(p->mosix.held_allocated *
-					    sizeof (struct held_files),
-					    GFP_KERNEL))) {
-		p->mosix.held_allocated = 0;
-		return (-ENOMEM);
-	}
-	for (i = 0; i < current->mosix.held_allocated; i++)
-		if ((fp = (struct file *) current->mosix.held_files[i].f)) {
-			get_file(fp);
-			p->mosix.held_files[i].f = fp;
-			if ((p->mosix.held_files[i].denywrite =
-			     current->mosix.held_files[i].denywrite))
-				atomic_dec(&fp->f_dentry->d_inode->
-					   i_writecount);
-		} else
-			p->mosix.held_files[i].f = NULL;
-	return (0);
-}
-
-void
-mosix_clear_all_held_files(struct task_struct *p)
-{
-	unsigned int i;
-	int n;
-	struct held_files *h;
-
-	if (!(n = p->mosix.held_allocated))
-		return;
-	h = p->mosix.held_files;
-	task_lock(p);
-	p->mosix.held_files = NULL;
-	p->mosix.held_allocated = 0;
-	task_unlock(p);
-	for (i = 0; i < n; i++)
-		if (h[i].f) {
-			if (h[i].denywrite)
-				allow_write_access(h[i].f);
-			fput(h[i].f);
-		}
-	kfree(h);
-}
-
-int
-task_maps_ip(struct task_struct *p, struct inode *ip)
-{
-	unsigned int i;
-	int n;
-	int ret = 0;
-	struct held_files *h;
-
-	task_lock(p);
-	if ((n = p->mosix.held_allocated))
-		for (h = p->mosix.held_files, i = 0; i < n; i++)
-			if (h[i].f && (h[i].f)->f_dentry->d_inode == ip) {
-				ret = 1;
-				break;
-			}
-	task_unlock(p);
-	return (ret);
-}
diff -Naur linux-2.4.26-om1/hpc/service.c linux-2.4.26-om1-o/hpc/service.c
--- linux-2.4.26-om1/hpc/service.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/service.c	2006-05-07 17:56:02.000000000 +0530
@@ -227,6 +227,7 @@
  	struct vm_area_struct *vma;
  	int count = 0;
  	int isfile;
+	int isshared = 0;
  	unsigned long start, addr, pgd_end, pmd_end, pte_end;
  	pgd_t *pgdir;
  	pmd_t *pmdir;
@@ -254,6 +255,7 @@
  				start = addr;
  			pgdir = pgd_offset(mm, start);
  			isfile = (vma->vm_file != NULL);
+			isshared = !(!(vma->vm_flags & VM_SHARED));
  			for (addr = start; addr < vma->vm_end;
  			     addr = pgd_end, pgdir++) {
  				if (let_go-- == 0) {
@@ -281,8 +283,8 @@
  						if (pte_end > pmd_end)
  							pte_end = pmd_end;
  						if (pte_present(*pte) ?
-						    (isfile
-						     &&
!pte_really_dirty(*pte))
+						    (isfile &&
+						    	 (isshared ||
!pte_really_dirty(*pte)))
  						    : pte_none(*pte)) {
  							if (isfile
  							    &&
count_in_file)
diff -Naur linux-2.4.26-om1/hpc/shm_comm.c linux-2.4.26-om1-o/hpc/shm_comm.c
--- linux-2.4.26-om1/hpc/shm_comm.c	1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/shm_comm.c	2006-05-07 17:56:02.000000000 +0530
@@ -0,0 +1,452 @@
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/poll.h>
+#include <linux/hpcctl.h>
+#include <net/sock.h>
+#include <hpc/defs.h>
+#include <hpc/routines.h>
+#include <hpc/protocol.h>
+#include <linux/hpc.h>
+#include <asm/uaccess.h>
+#include <linux/smp_lock.h>
+#include <linux/swap.h>
+#include <linux/pagemap.h>
+#include <linux/stddef.h>
+#include <hpc/comm.h>
+#include <hpc/debug.h>
+#include <hpc/hpcversion.h>
+#include <hpc/balance.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
+
+
+static char MIGSHMDSTR[] = "MigShmD";
+
+
+static struct mosix_addr *fill_to_addr(int mos,struct mosix_addr
*to,unsigned short int port);
+
+
+static int
+info_recv_message(struct shm_request *request);
+
+int
+mosix_migshm_daemon(void *nothing)
+{
+        struct task_struct *p = current;
+	struct shm_request shm_req;
+	static struct mosix_link *link;
+
+        common_daemon_setup(MIGSHMDSTR, 1);
+
+ restart:
+         wait_for_mosix_configuration(NULL);
+
+         if (!p->mosix.contact) {
+		if(!(link = comm_open(COMM_MIGSHM,0,0UL))) 
+			goto h;
+                 comm_use(p, link);
+                 if (!p->mosix.contact)
+                 {
+                 h:     printk("%s: failed comm_open -
exiting\n",MIGSHMDSTR);
+			if(p->mosix.contact)
+                                 comm_close(NULL);
+                      	do_exit(0);
+                 }
+         }
+ 
+         while (1) {
+                 comm_wait();
+ 
+                 /* if openMosix was shut down - restart everything */
+                 if (!PE) {
+                         comm_close(NULL);
+                         comm_free_linkpool();
+                         goto restart;
+                 }
+ 
+                 info_recv_message(&shm_req);
+         }
+ }
+
+static int
+info_recv_message(struct shm_request *request)
+{
+      	struct mosix_addr ra;   /* reply address */
+      	struct mosix_link *l = current->mosix.contact;
+      	struct shm_page *shm_page;
+	struct page *page;
+	int n;
+      	int sender;
+	unsigned long dummy;
+      	while (1) {
+              	n = comm_recvfrom(request, sizeof(struct shm_request), l,
&ra, 0);
+              	if (n == -EDIST )
+                      continue;       /* message > bufsize */
+
+              	if (n < 0)
+                      return (0);
+
+              	if (n < sizeof (struct shm_request)) {
+                      	continue;
+              	}
+              	sender = request->pe;
+             	if (sender > MAXPE ||((request->which != INVALIDATE) &&
(sender != net_to_mos(&ra)))) {
+                      continue;
+              	}
+
+              	if (sender == PE) {
+                      printk
+                          ("WARNING: Another computer is masquerading as
same openMosix node as this (%d)!\n",
+                           PE);
+            		continue;
+              	}
+		if((request->which == GET_FILE) || (request->which ==
PUT_FILE)) {
+			unsigned long dummy = 0;
+ 
+
+			if(request->which == GET_FILE)
+				get_file((struct file
*)request->rem_shm_page_addr);
+			else 
+				fput((struct file
*)request->rem_shm_page_addr);
+
+			comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+			continue;
+		}
+ 
+		shm_page = request->rem_shm_page_addr;
+ 
+		shm_pagecache_get(shm_page);
+ 
+		switch(request->which) {
+
+			case INVALIDATE:
+
+				if(!(shm_page->state & AT_HOME)) {
+					page =
find_get_page(shm_page->mapping,shm_page->index);
+ 
+					invalidate(shm_page,page,1);
+
+				       	page_cache_release(page);
+				}
+
+				request->rem_shm_page_addr =
shm_page->next_addr;
+
+				if(request->next == 0) 
+					request->next = ((struct sockaddr_in
*)(&(ra.saddr)))->sin_port;
+
+				if(shm_page->next != request->pe) 
+                                	comm_sendto(shm_page->next, request,
sizeof (struct shm_request), l,
+
fill_to_addr(shm_page->next,&ra,MIGSHM_DEAMON_PORT));
+				else 
+					comm_sendto(shm_page->next,
&dummy,sizeof(dummy),l,
+
fill_to_addr(shm_page->next,&ra,request->next));
+
+				break;
+
+
+			case FORWARD_REQUEST_READ:
+                	case FORWARD_REQUEST_WRITE:
+ 
+				if(request->which & FORWARD_REQUEST_READ) {
+					shm_page->next = request->next;
+					shm_page->next_addr =
request->next_addr; 
+					shm_page->prev = request->prev;
+					shm_page->prev_addr =
request->prev_addr;
+				} 
+
+				page =
find_get_page(shm_page->mapping,shm_page->index);
+
+				invalidate(shm_page,page,(request->which &
FORWARD_REQUEST_WRITE)); 
+
+
comm_sendto(COMM_TOADDR,kmap(page),PAGE_SIZE,l,&ra);
+				kunmap(page);
+ 
+				page_cache_release(page);
+ 
+				break;
+ 
+			case WRITE_BACK:
+				{
+
+				struct mosix_link *mlink=NULL;
+				struct mosix_addr from;
+ 
+				spin_lock(&shm_page->shm_lock); 
+
+				if(shm_page->state & PERM_ERR) {
+                                        shm_page->state &=
~(PERM_ERR|STATE_MASK);
+					shm_page->state |= BUSY_EXCLUSIVE;
+					shm_page->readers =
shm_page->writers = 0;
+					dummy = 0;
+					spin_unlock(&shm_page->shm_lock);
+					goto l;
+				}
+
+				switch(shm_page->state & STATE_MASK) {
+ 
+					case BUSY_SHARED:
+               	 			case BUSY_EXCLUSIVE:
+
+
spin_unlock(&shm_page->shm_lock);
+                        			dummy = 1;
+                        			break;
+
+                			case EXCLUSIVE: 
+
+						if(!shm_page->readers) {
+                        				shm_page->state &= ~
EXCLUSIVE;
+                        				shm_page->state |=
BUSY_EXCLUSIVE;
+                        				dummy = 0;
+						} else
+							dummy = 1;
+
+
spin_unlock(&shm_page->shm_lock);
+                       	 			break;
+				}
+			l:
+
+				if(!dummy) {
+					mlink = comm_open(MIGSHM_COMM,
&from,comm_connect_timo);
+					if(!mlink) break;
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),mlink,&ra);
+				} else
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+
+				if(!dummy) {
+
+					page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+
+
comm_recvfrom(kmap(page),PAGE_SIZE,mlink,&ra,0);
+        				SetPageUptodate(page);
+        				set_page_dirty(page);
+        				shm_page->owner = PE;
+        				unlock_page(page);
+					kunmap(page);
+        				spin_lock(&shm_page->shm_lock);
+        				shm_page->state &= ~BUSY_EXCLUSIVE;
+        				shm_page->state |= EXCLUSIVE;
+        				spin_unlock(&shm_page->shm_lock);
+
+        				page_cache_release(page);
+					comm_close(mlink);
+        				shm_pagecache_release(shm_page);
+				}
+
+				}
+
+				break;
+
+			case DROP_PAGE_START:
+
+				dummy = 1;
+ 
+				spin_lock(&shm_page->shm_lock);
+ 
+				if(shm_page->state & UPGRADE_ERR)
+					dummy = 2;
+				else
+				if(((shm_page->state & STATE_MASK) ==
SHARED) &&  !(shm_page->state & DROPPING)) {
+						shm_page->state |= DROPPING;
+						dummy = 0;
+				}
+
+				spin_unlock(&shm_page->shm_lock); 
+
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+ 
+
+				break;
+
+			case DROP_PAGE_END:
+ 
+				shm_page->state &= ~DROPPING;
+				break;
+
+			case DROP_PREV:
+ 
+				shm_page->prev = request->prev;
+				shm_page->prev_addr = request->prev_addr;
+ 
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+
+				break;
+
+			case DROP_NEXT:
+ 
+				shm_page->next = request->next;
+				shm_page->next_addr = request->next_addr;
+
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+				break;
+		}
+
+		shm_pagecache_release(shm_page);
+	}
+}
+
+struct mosix_addr * fill_to_addr(int mos,struct mosix_addr *to,unsigned
short int port)
+{
+	struct sockaddr_in *sa = (struct sockaddr_in *)(&(to->saddr));
+	if(!mos_to_net(mos,sa)) {
+		return NULL;
+	}
+	sa->sin_port = port;
+	return  to;
+}
+
+int shm_send_message(int mos,struct shm_page *shm_page,struct page
*buf_page,int which)
+{
+        struct mosix_addr to,from;
+        struct shm_request request;
+        struct task_struct *p = current;
+        int res = 1 ;
+	struct mosix_link *mlink = NULL;
+
+        if(mos && (!fill_to_addr(mos,&to,MIGSHM_DEAMON_PORT))) 
+                goto out;
+ 
+     	mlink = comm_open(MIGSHM_COMM, &from,comm_connect_timo);
+	if(!mlink)
+		goto out; 
+	res = 0;
+	request.pe = PE;
+        switch(which) {
+
+                case FORWARD_REQUEST_READ:
+		case FORWARD_REQUEST_WRITE:
+ 
+                        request.which = which;
+ 
+			if(which == FORWARD_REQUEST_READ) { 
+				request.next = request.prev = PE;
+				request.next_addr = request.prev_addr =
shm_page;
+
+				if(shm_page->prev != mos) {
+					request.next = shm_page->prev;
+					request.next_addr =
shm_page->prev_addr;
+				}
+			} 
+ 
+			request.rem_shm_page_addr =
shm_page->rem_shm_page_addr;
+ 
+			if((comm_sendto(mos, &request, sizeof (struct
shm_request), mlink,&to) < 0) ||
+			   (comm_recvfrom(kmap(buf_page),PAGE_SIZE, mlink
,&from,GTIME_OUT) <= 0)) 
+				res = 1; 
+ 
+			kunmap(buf_page);
+
+                        break;
+
+		case INVALIDATE:
+
+			request.which = INVALIDATE;
+			request.rem_shm_page_addr = shm_page->next_addr;
+ 
+			request.next = 0;
+
+			if((comm_sendto(mos ,&request,sizeof(struct
shm_request), mlink, &to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,INT_TIME_OUT) <= 0))
+				res = 1;
+			break; 
+ 
+		case WRITE_BACK:
+
+			request.which = WRITE_BACK;
+			request.rem_shm_page_addr =
shm_page->rem_shm_page_addr;
+ 
+			if((comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+				res = 1;
+
+			if(!res) {
+ 
+
if(comm_sendto(mos,kmap(buf_page),PAGE_SIZE,mlink,
+							&from) < 0 )
+                            		res = 1;
+				kunmap(buf_page);
+			}
+ 
+			break;
+
+		case DROP_PAGE:
+ 
+			request.which = DROP_PAGE_START;
+			request.rem_shm_page_addr =
shm_page->rem_shm_page_addr;
+
+			if((comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+				res = 1;
+
+			if(!res) {
+ 
+        case DROP_NEXTPREV:
if(!fill_to_addr(shm_page->prev,&to,MIGSHM_DEAMON_PORT)) {
+                			res = 1;
+					break;
+				}
+	case DROP_NEXT:
+				request.which = DROP_NEXT;
+				request.rem_shm_page_addr =
shm_page->prev_addr;
+				request.next = shm_page->next;
+				request.next_addr = shm_page->next_addr;
+
+
if((comm_sendto(shm_page->prev,&request,sizeof(struct
shm_request),mlink,&to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+					res = 1;
+
+				if(which == DROP_NEXT) 
+					break;
+
+
if(!fill_to_addr(shm_page->next,&to,MIGSHM_DEAMON_PORT)) {
+                                        res = 1;
+					break;
+				}
+ 
+				request.which = DROP_PREV;
+                                request.rem_shm_page_addr =
shm_page->next_addr;
+                                request.prev = shm_page->prev;
+                                request.prev_addr = shm_page->prev_addr;
+
+
if((comm_sendto(shm_page->next,&request,sizeof(struct
shm_request),mlink,&to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+					res = 1;
+
+				if(which == DROP_NEXTPREV) 
+					break;
+ 
+ 
+
if(!fill_to_addr(mos,&to,MIGSHM_DEAMON_PORT)) {
+                                        res = 1; 
+					break;
+				}
+ 
+		case DROP_PAGE_END:
+
+				request.which = DROP_PAGE_END; 
+				request.rem_shm_page_addr =
shm_page->rem_shm_page_addr;
+ 
+				if(comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to) < 0)
+					res = 1;
+			}
+
+			break; 
+
+		case GET_FILE:
+		case PUT_FILE:
+
+			request.which = which;
+			request.rem_shm_page_addr = (struct shm_page
*)shm_page;
+ 
+                       	if((comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to)<0) || 
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0)) 
+				res = 1;
+
+			break; 
+        }
+
+      	comm_close(mlink);
+out:
+        return res;
+}
+
diff -Naur linux-2.4.26-om1/hpc/shm_filemap.c
linux-2.4.26-om1-o/hpc/shm_filemap.c
--- linux-2.4.26-om1/hpc/shm_filemap.c	1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/shm_filemap.c	2006-05-07
17:56:02.000000000 +0530
@@ -0,0 +1,209 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/locks.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/blkdev.h>
+#include <linux/file.h>
+#include <linux/swapctl.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include<linux/wait.h>
+#include <linux/iobuf.h>
+ 
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/mman.h>
+#include <asm/atomic.h>
+ 
+#include <linux/highmem.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
+
+LIST_HEAD(shm_page_unused_list);
+
+
+spinlock_cacheline_t shm_pagecache_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+
+
+unsigned int shm_page_hash_bits;
+
+struct shm_page **shm_page_hash_table;
+
+void shm_pagecache_release(struct shm_page *shm_page)
+{
+	if(atomic_read(&shm_page->count) == 0) 
+		BUG();
+
+	spin_lock(&shm_pagecache_lock); 
+
+	atomic_dec(&shm_page->count);
+
+        if((atomic_read(&shm_page->count) == 1) && shm_page->mapping) 
+		remove_shm_page(shm_page);
+
+	if((atomic_read(&shm_page->count) == 0)) 
+		list_add(&shm_page->list, &shm_page_unused_list);
+
+	spin_unlock(&shm_pagecache_lock);
+}
+
+static void add_page_to_hash_queue(struct shm_page * page, struct shm_page
**p)
+ {
+         struct shm_page *next = *p;
+ 
+         *p = page;
+         page->next_hash = next;
+          page->pprev_hash = p;
+         if (next)
+                  next->pprev_hash = &page->next_hash;
+ }
+static inline void __add_to_page_cache(struct shm_page * page,
+         struct address_space *mapping, unsigned long offset,
+         struct shm_page **hash)
+ { 
+ 
+       	shm_pagecache_get(page); 
+      	page->index = offset;
+	page->mapping = mapping;
+       	add_page_to_hash_queue(page, hash);
+ }
+void add_to_shm_page_cache(struct shm_page * page, struct address_space *
mapping, unsigned long offset)
+{
+         spin_lock(&shm_pagecache_lock);
+         __add_to_page_cache(page, mapping, offset, shm_page_hash(mapping,
offset));
+         spin_unlock(&shm_pagecache_lock);
+}
+
+static inline void remove_page_from_hash_queue(struct shm_page * page)
+{
+         struct shm_page *next = page->next_hash;
+         struct shm_page **pprev = page->pprev_hash;
+ 
+         if (next)
+                 next->pprev_hash = pprev;
+         *pprev = next;
+         page->pprev_hash = NULL;
+}
+
+void remove_shm_page(struct shm_page * page)
+ {
+	remove_page_from_hash_queue(page);
+	page->mapping  = NULL;
+	atomic_dec(&page->count);
+ }
+
+
+static struct shm_page *alloc_shm_page(void)
+{
+        struct shm_page *shm_page = NULL;
+	struct task_struct *p = current;
+ 
+	spin_lock(&shm_pagecache_lock);
+
+	if(!list_empty(&shm_page_unused_list)) {
+		shm_page = list_entry(shm_page_unused_list.prev,struct
shm_page,list);
+		list_del(&shm_page->list);
+	}
+
+	spin_unlock(&shm_pagecache_lock);
+
+	if(!shm_page) 
+		shm_page = kmem_cache_alloc(shm_page_cachep,SLAB_KERNEL);
+
+       	if(!shm_page)
+        	return NULL;
+
+ 
+	memset(shm_page,0,sizeof(struct shm_page));
+        atomic_set(&shm_page->count,1);
+        shm_page->owner = PE;
+	shm_page->prev = shm_page->next = PE;
+	shm_page->prev_addr = shm_page->next_addr = shm_page;
+	shm_page->mapping = NULL;
+	shm_page->readers = shm_page->writers = 0;
+	shm_page->shm_lock = SPIN_LOCK_UNLOCKED;
+	INIT_LIST_HEAD(&shm_page->list);
+        return shm_page;
+}
+
+static inline struct shm_page * __find_page_nolock(struct address_space
*mapping, unsigned long offset, 
+
struct shm_page *page)
+ {
+         goto inside;
+ 
+         for (;;) {
+                 page = page->next_hash;
+ inside:
+                 if (!page)
+                         goto not_found;
+                 if (page->mapping != mapping)
+                         continue;
+                 if (page->index == offset)
+                         break;
+         }
+ 
+ not_found:
+         return page;
+ }
+ 
+ /*
+  * a rather lightweight function, finding and getting a reference to a
+  * hashed page atomically.
+  */
+ struct shm_page * find_get_shm_page(struct address_space *mapping,
+                               unsigned long offset, struct shm_page
**hash)
+ {
+         struct shm_page *page;
+ 
+         /*
+          * We scan the hash list read-only. Addition to and removal from
+          * the hash-list needs a held write-lock.
+          */
+         spin_lock(&shm_pagecache_lock);
+         page = __find_page_nolock(mapping, offset, *hash);
+         if (page)
+                atomic_inc(&page->count);
+         spin_unlock(&shm_pagecache_lock);
+         return page;
+ }
+ /* 
+  * Same as above, but create the page if required..
+  */
+ struct shm_page * find_or_create_shm_page(struct address_space *mapping,
unsigned long index)
+ {
+         struct shm_page *page;
+         struct shm_page **hash = shm_page_hash(mapping, index);
+	 extern struct super_block bad_super_block;
+ 
+         page =	find_get_shm_page(mapping, index, hash);
+ 
+         if (!page) {
+                 struct shm_page *newpage = alloc_shm_page();
+                 if (newpage) {
+                         spin_lock(&shm_pagecache_lock);
+                         page = __find_page_nolock(mapping, index, *hash);
+                         if (likely(!page)) {
+				if((unsigned long)(mapping->host->i_sb) ==
(unsigned long)(&bad_super_block))
+                        		newpage->state |= IDLE;
+                 		else {
+                        		newpage->state |= EXCLUSIVE;
+                        		newpage->state |= AT_HOME;
+                 		}
+
+                               	page = newpage;
+                               	__add_to_page_cache(page, mapping,
index, hash);
+                               	newpage = NULL;
+                         }  else
+				shm_pagecache_get(page);
+                         spin_unlock(&shm_pagecache_lock);
+                         if (newpage)
+                                 shm_pagecache_release(newpage);
+                 }
+         } 
+	return page;
+ }
+
diff -Naur linux-2.4.26-om1/hpc/syscalls.c linux-2.4.26-om1-o/hpc/syscalls.c
--- linux-2.4.26-om1/hpc/syscalls.c	2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/syscalls.c	2006-05-07 17:56:02.000000000 +0530
@@ -1733,6 +1733,10 @@
  			break;
  		}
  		break;
+	case SHMGET:
+	case SHMAT:
+	case SHMDT:
+	case SEMGET:
  	case MSGGET:		/* added this so we can return -EINVAL in
the default */
  		break;
  	case MSGCTL:
diff -Naur linux-2.4.26-om1/include/asm-i386/pgtable.h
linux-2.4.26-om1-o/include/asm-i386/pgtable.h
--- linux-2.4.26-om1/include/asm-i386/pgtable.h	2006-05-08
15:02:19.000000000 +0530
+++ linux-2.4.26-om1-o/include/asm-i386/pgtable.h	2006-05-08
10:49:51.000000000 +0530
@@ -201,7 +201,7 @@
  #define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)

  #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
-#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
_PAGE_ACCESSED)
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT |_PAGE_RW | _PAGE_USER |
_PAGE_ACCESSED)
  #define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_USER |
_PAGE_ACCESSED)
  #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER |
_PAGE_ACCESSED)

diff -Naur linux-2.4.26-om1/include/hpc/comm.h
linux-2.4.26-om1-o/include/hpc/comm.h
--- linux-2.4.26-om1/include/hpc/comm.h	2006-05-08 15:02:24.000000000 +0530
+++ linux-2.4.26-om1-o/include/hpc/comm.h	2006-05-07
17:56:02.000000000 +0530
@@ -19,6 +19,9 @@

  #ifdef __KERNEL__

+#define MIGSHM_DEAMON_PORT 0x3419
+
+
  struct mosix_link;			/* defined in hpc/comm.c */
  struct mosix_addr;			/* defined in include/hpc/protocol.h
*/
  struct mosix_task;
@@ -35,7 +38,11 @@
  #define COMM_ACCEPT	(70002)
  #define COMM_MIGD	(70003)
  #define COMM_INFO	(70004)
+#define COMM_MIGSHM     (70006)
  #define	COMM_LOOSE	(70005)
+#define MIGSHM_COMM	(70007)
+
+

  /*
   * message flags:
@@ -77,6 +84,9 @@

  #define COMM_HLEN	(sizeof(struct comm_header))

+#define GTIME_OUT	1
+#define INT_TIME_OUT 	2
+
  /*
   * exported data
   */
@@ -89,6 +99,7 @@
   * communication module interface
   */

+extern int comm_getname(struct socket *sock, struct sockaddr *saddr);
  extern void comm_startup(void);
  extern mosix_link *comm_open(int, mosix_addr *, unsigned long);
  extern mosix_link *comm_use(struct task_struct *, mosix_link *);
@@ -119,7 +130,7 @@
  extern mosix_link *comm_borrow_linkpool(void);
  extern void comm_return_linkpool(mosix_link *);
  extern void comm_age_linkpool(void);
-extern void rinode_flush_files(int);
+

  extern spinlock_t skown_lock;

diff -Naur linux-2.4.26-om1/include/hpc/hpctask.h
linux-2.4.26-om1-o/include/hpc/hpctask.h
--- linux-2.4.26-om1/include/hpc/hpctask.h	2006-05-08
15:02:24.000000000 +0530
+++ linux-2.4.26-om1-o/include/hpc/hpctask.h	2006-05-07
17:56:02.000000000 +0530
@@ -49,12 +49,6 @@
  	volatile long bstate;		/* backed-up state while in MOSIX */
  	rwlock_t state_lock;		/* changes of bstate */
  	kernel_cap_t remote_caps;	/* effective capabilities on REMOTE
*/
-	struct held_files
-	{
-		struct file *f;		/* a file in use */
-		char denywrite;		/* whether holding i_writecount down
*/
-	} *held_files;			/* files held by remote VM */
-	int held_allocated;		/* # of entries in "held_inodes" */
  	struct mosix_link *contact;	/* DEPUTY <==> REMOTE connection */
  	struct task_struct *ancesstor;	/* nearest ancesstor when dependent
*/
  	uint32_t deputytime;		/* ticks spent on DEPUTY */
@@ -194,7 +188,6 @@
  #define	DTRACESYS2	0x00004000	/* syscall done before 2nd
PT_TRACESYS*/
  #define	DMUSTBEBACK	0x00008000	/* MUST arrive back home */
  #define	DDUMPABLE	0x00010000	/* copy of dumpable when
DEPUTY */
-#define	DDELAYHELD	0x00020000	/* rebuild held_files later
*/
  #define DTDUMPABLE      0x00040000      /* copy of task_dumpable when
DEPUTY */
  #define DMIGFILTER	0x00040000	/* process migration is conditioned
*/
  #ifdef CONFIG_MOSIX_DFSA
@@ -214,7 +207,6 @@
  #define	DREQ_URGENT		0x00000020	/* something urgent
(R=>D) */
  #define	DREQ_CAPCNG		0x00000040	/* capabilities
changed */
  #define	DREQ_INFOCNG		0x00000080	/* disclosed info
changed */
-#define	DREQ_FILEUNMAP		0x00000100	/* file(s) were
unmapped */
  #ifdef CONFIG_MOSIX_DFSA
  #define	DREQ_NOTUPTODATE	0x10000000	/* send it all again
*/
  #define	DREQ_DFSASYNC		0x20000000	/* DFSA world
changed */
@@ -232,7 +224,6 @@
   * reasons to stay:
   */

-#define DSTAY_FOR_MONKEY 0x00000001	/* using monkey vnode */
  #define DSTAY_FOR_DEV	 0x00000002	/* mapping a device */
  #define DSTAY_FOR_86	 0x00000004	/* running in 86 mode */
  #define DSTAY_SYSTEM	0x00000008	/* system process (init, oM daemon)
*/
@@ -249,7 +240,7 @@
  #define DNOMIGRATE	0x80000000	/* user requested no auto-migrations
*/

  #define DSTAY   (~DNOMIGRATE)
-#define	DSTAY_PER_MM
(DSTAY_FOR_MONKEY|DSTAY_FOR_DEV|DSTAY_FOR_MLOCK|DSTAY_FOR_KIOBUF)
+#define	DSTAY_PER_MM
(DSTAY_FOR_DEV|DSTAY_FOR_MLOCK|DSTAY_FOR_KIOBUF)

  /*
   * where to go (whereto)
diff -Naur linux-2.4.26-om1/include/hpc/mig_shm.h
linux-2.4.26-om1-o/include/hpc/mig_shm.h
--- linux-2.4.26-om1/include/hpc/mig_shm.h	1970-01-01
05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/include/hpc/mig_shm.h	2006-05-07
17:56:02.000000000 +0530
@@ -0,0 +1,73 @@
+#ifndef _MIG_SHM_H
+#define _MIG_SHM_H
+struct shm_pgentry;
+struct shm_page {
+	struct list_head list; 
+	struct address_space *mapping;
+	unsigned long index;
+        struct shm_page *next_hash; 
+        atomic_t count;
+	int prev,next; 
+        unsigned long state; 
+        struct shm_page **pprev_hash; 
+	unsigned int owner;
+	unsigned int readers;
+	unsigned int writers;
+	struct shm_page *rem_shm_page_addr,*prev_addr,*next_addr;
+	spinlock_t shm_lock;
+};
+
+/*
+struct shm_request {
+	unsigned long which;
+	int pe; 
+	struct shm_page *rem_shm_page_addr;
+	struct shm_page *next_addr,*prev_addr;
+	unsigned long prev,next;
+	struct mosix_addr from;
+};
+struct wb_reply {
+	unsigned long dummy;
+	struct mosix_addr from;
+};
+*/
+
+#define 	IDLE 			0x00000001
+#define 	SHARED			0x00000002
+#define 	EXCLUSIVE 		0x00000004
+#define 	BUSY_SHARED		0x00000008
+#define 	BUSY_EXCLUSIVE  	0x00000010
+
+#define 	DROPPING  		0x00000020
+
+#define 	WITH_WRITE_ACC  	0x00000040
+#define 	WITH_READ_ACC   	0x00000080
+#define 	AT_HOME 		0x00000200
+
+#define 	INVALIDATE 		0x00000001
+#define 	WRITE_BACK		0x00000002
+#define 	DROP_PAGE		0x00000004
+#define 	DROP_PAGE_START		0x00000008
+#define 	DROP_PAGE_END		0x00000010
+#define 	DROP_PREV 		0x00000020
+#define 	DROP_NEXT		0x00000040
+#define 	DROP_NEXTPREV		0x00000080
+#define 	FORWARD_REQUEST_WRITE 	0x00000200
+#define 	FORWARD_REQUEST_READ 	0x00000400
+#define  	GET_FILE		0x00000800
+#define 	PUT_FILE		0x00001000
+#define 	UPGRADE_ERR		0x00002000
+#define		PERM_ERR		0x00004000
+
+#define     	ACC_MASK		(WITH_WRITE_ACC|WITH_READ_ACC)
+#define 	STATE_MASK
(IDLE|SHARED|EXCLUSIVE|BUSY_SHARED|BUSY_EXCLUSIVE)
+
+extern void invalidate(struct shm_page *shm_page,struct page *page,int
write_access);
+extern struct page *get_nopage(struct vm_area_struct *vma, unsigned long
address,struct shm_page **shm_page,int write_access);
+extern void wait_here(void);
+
+
+#endif
+
+
+ 
diff -Naur linux-2.4.26-om1/include/hpc/protocol.h
linux-2.4.26-om1-o/include/hpc/protocol.h
--- linux-2.4.26-om1/include/hpc/protocol.h	2006-05-08
15:02:24.000000000 +0530
+++ linux-2.4.26-om1-o/include/hpc/protocol.h	2006-05-07
17:56:02.000000000 +0530
@@ -59,6 +59,7 @@
  	int fixed;
  	unsigned long len;
  	unsigned long flags;
+	unsigned long prot;
  	unsigned long pgoff;
  	int origin;
  	struct file *fp;
@@ -175,13 +176,48 @@
  	struct file *fp;
  	unsigned long offset;
  	nopage_t nopage;
+	int access;
+	struct shm_page *rem_shm_page_addr;
+};
+struct write_page_h
+{
+	struct dentry *dentry;
+	unsigned long offset;
+};
+struct to_be_unlocked_h
+{
+	struct shm_page *shm_page;
+	struct page *page;
  };

-struct page_ret_h
+/*struct page_ret_h
  {
  	int ret;
  	unsigned long deputytime;
  };
+*/
+struct upgrade_h 
+{
+	struct shm_page *shm_page,*rem_shm_page_addr;
+};
+
+struct shm_request {
+        unsigned long which;
+        int pe;
+        struct shm_page *rem_shm_page_addr;
+        struct shm_page *next_addr,*prev_addr;
+        unsigned long prev,next;
+};
+
+struct shm_page_ret_h
+{
+	int ret;
+	 unsigned long deputytime;
+	struct shm_page *rem_shm_page_addr;
+	struct shm_page *next_addr,*prev_addr;
+	unsigned long prev,next;
+
+};

  struct rlimit_h
  {
@@ -459,6 +495,8 @@
  #define	REM_BRING_ME_REGS	(ANYTIME|0x04)
  #define	REM_GETALOAD		(ANYTIME|0x05)
  #define	REM_GETTSC		(ANYTIME|0x06)
+#define REM_UPGRADE	        (ANYTIME|0x07)
+//#define REM_WRITE_BACK_PERM     (ANYTIME|0X08)

  #define	REM_NULLMSG		0x01
  #define	REM_ASIG		0x02
@@ -492,10 +530,13 @@
  extern void deputy_add_rusage(struct rusage *);
  extern void deputy_analyse_remote_signals(struct asig_h *);
  extern int deputy_bring_page(struct bring_page_h *);
+extern int deputy_upgrade(struct upgrade_h *);
  extern int deputy_tsc(void);
  extern int deputy_more_strings(struct execve_more_strings_h *);
  extern int deputy_bring_me_regs(unsigned long *);
  extern void deputy_inform_remote_of_overheads(void);
+extern int deputy_writepage(struct write_page_h *g);
+extern int deputy_unlock_page(struct to_be_unlocked_h *head);

  /* routines on the REMOTE side of the protocol: */

@@ -511,7 +552,9 @@
  extern int remote_setup_args(struct execve_setup_args_h *);
  extern int remote_exec_mmap(void);
  extern int remote_urgent(void);
+extern int remote_upgrade(struct shm_page *);
  extern int remote_readpage(struct file *, struct page *);
+extern int remote_writepage(struct page *);
  extern int remote_dump_thread(void);
  extern int remote_init_aout_mm(struct exec *);
  extern int remote_elf_setup(struct execve_elf_setup_h *);
@@ -535,7 +578,6 @@
  extern int remote_verify_write(struct user_copy_h *);
  extern int remote_csum_copy_from_user(struct user_csum_copy_h *);
  extern int remote_csum_copy_to_user(struct user_csum_copy_h *);
-extern int remote_report_files(void);
  extern int remote_setup_frame(struct setupframe_parameters_h *);
  extern int remote_nice(long *);
  extern int remote_caps(kernel_cap_t *);
@@ -565,6 +607,12 @@
  extern unsigned int which_regs_to_send(void);
  extern void regs_were_sent(void);

+
+
+extern int mosix_migshm_daemon(void *nothing);
+extern int shm_send_message(int mos,struct shm_page *shm_page,struct page
*buf_page,int which);
+
+
  #endif /*__KERNEL__*/
  #endif /* CONFIG_MOSIX */
  #endif
diff -Naur linux-2.4.26-om1/include/hpc/routines.h
linux-2.4.26-om1-o/include/hpc/routines.h
--- linux-2.4.26-om1/include/hpc/routines.h	2006-05-08
15:02:24.000000000 +0530
+++ linux-2.4.26-om1-o/include/hpc/routines.h	2006-05-07
17:56:02.000000000 +0530
@@ -122,11 +122,8 @@
  extern void deputy_main_loop(void);
  extern void undeputy(struct task_struct *);
  extern void deputy_async_requests(void);
-extern void mosix_clear_all_held_files(struct task_struct *);
-extern int fork_mosix_remote_files(struct task_struct *);
  extern void coordinate(int, int);
  extern long call_with_regs(void *, struct pt_regs *, struct pt_regs *);
-extern int task_maps_ip(struct task_struct *, struct inode *);
  extern void deputy_communication_failed(void);
  extern void deputy_die_on_communication(void) ATTRIB_NORET;

@@ -204,6 +201,9 @@
  extern int my_mosix_status(void);
  extern void set_my_cpuspeed(void);

+
+extern int mosix_migshm_daemon(void *);
+
  /* debugging: */

  /* macros: */
diff -Naur linux-2.4.26-om1/include/hpc/shm_pagemap.h
linux-2.4.26-om1-o/include/hpc/shm_pagemap.h
--- linux-2.4.26-om1/include/hpc/shm_pagemap.h	1970-01-01
05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/include/hpc/shm_pagemap.h	2006-05-07
17:56:02.000000000 +0530
@@ -0,0 +1,39 @@
+#ifndef _SHM_PAGEMAP_H
+#define _SHM_PAGEMAP_H
+extern unsigned int shm_page_hash_bits;
+#define SHM_PAGE_HASH_BITS      (shm_page_hash_bits)
+#define SHM_PAGE_HASH_SIZE      (1<<SHM_PAGE_HASH_BITS)
+
+extern struct shm_page **shm_page_hash_table;
+
+#define shm_wait_table_bits   6
+#define shm_wait_table_shift  BITS_PER_LONG - shm_wait_table_bits;
+
+extern struct list_head shm_page_unused_list; 
+
+
+extern spinlock_cacheline_t shm_pagecache_lock_cacheline;
+#define shm_pagecache_lock (shm_pagecache_lock_cacheline.lock)
+ 
+static inline unsigned long _shm_page_hashfn(struct address_space *
mapping, unsigned long index)
+{
+#define i (((unsigned long) mapping)/(sizeof(struct inode) & ~
(sizeof(struct inode) - 1)))
+#define s(x) ((x)+((x)>>SHM_PAGE_HASH_BITS))
+        return s(i+index) & (SHM_PAGE_HASH_SIZE-1);
+#undef i
+#undef s
+}
+ 
+#define shm_page_hash(mapping,index) (shm_page_hash_table +
_shm_page_hashfn(mapping,index))
+ 
+
+#define shm_pagecache_get(shm_page) (atomic_inc(&shm_page->count))
+
+extern void shm_pagecache_release(struct shm_page *shm_page);
+extern struct shm_page * find_or_create_shm_page(struct address_space
*mapping, unsigned long index);
+extern void add_to_shm_page_cache(struct shm_page * page, struct
address_space * mapping, unsigned long offset);
+extern void remove_shm_page(struct shm_page * page);
+extern struct shm_page * find_get_shm_page(struct address_space *mapping,
+                               unsigned long offset, struct shm_page
**hash);
+
+#endif
diff -Naur linux-2.4.26-om1/include/linux/hpc.h
linux-2.4.26-om1-o/include/linux/hpc.h
--- linux-2.4.26-om1/include/linux/hpc.h	2006-05-08
15:02:28.000000000 +0530
+++ linux-2.4.26-om1-o/include/linux/hpc.h	2006-05-08
10:49:51.000000000 +0530
@@ -22,10 +22,6 @@

  /* operations on DEPUTY's data-base of REMOTE files: */

-extern int mosix_register_a_file(struct file *, int);
-extern void mosix_undo_last_file_registration(struct file *, int);
-extern int mosix_rebuild_file_list(void);
-extern void mosix_update_remote_files(void);

  struct vmalist
  {
@@ -60,8 +56,6 @@
  extern void mosix_exit(void);
  extern void mosix_very_exit(void);
  extern void mosix_obtain_registers(unsigned long);
-extern void mosix_bring_monkey_users_back(struct inode *);
-extern void mosix_no_longer_monkey(struct inode *);
  extern void mosix_check_for_freedom_to_move(void);
  extern int mosix_pre_clone(void);
  extern void mosix_post_clone(void);
@@ -126,7 +120,6 @@
   */

  #define	FATAL_SIGSEGV		SIGINT
-#define	REMOTE_FILE_RELEASED	SIGQUIT

  /* other signals that can occur on REMOTE:
   * SIGKILL, SIGSEGV, SIGPROF, SIGVTALRM, SIGFPE, SIGBUS, SIGIOT, SIGILL,
diff -Naur linux-2.4.26-om1/include/linux/mm.h
linux-2.4.26-om1-o/include/linux/mm.h
--- linux-2.4.26-om1/include/linux/mm.h	2006-05-08 15:02:27.000000000 +0530
+++ linux-2.4.26-om1-o/include/linux/mm.h	2006-05-08
10:49:51.000000000 +0530
@@ -183,6 +183,7 @@
  #ifdef CONFIG_MOSIX
  	char young;
  	unsigned long last_young;
+	struct shm_page *shm_page;
  #endif /* CONFIG_MOSIX */
  } mem_map_t;

@@ -429,6 +430,7 @@
   */
  #define NOPAGE_SIGBUS	(NULL)
  #define NOPAGE_OOM	((struct page *) (-1))
+#define PAGE_BUSY 	((struct page *) (-2))

  /* The array of struct pages */
  extern mem_map_t * mem_map;
diff -Naur linux-2.4.26-om1/include/linux/slab.h
linux-2.4.26-om1-o/include/linux/slab.h
--- linux-2.4.26-om1/include/linux/slab.h	2006-05-08
15:02:27.000000000 +0530
+++ linux-2.4.26-om1-o/include/linux/slab.h	2006-05-08
10:49:51.000000000 +0530
@@ -74,6 +74,9 @@
  extern kmem_cache_t	*bh_cachep;
  extern kmem_cache_t	*fs_cachep;
  extern kmem_cache_t	*sigact_cachep;
+#ifdef CONFIG_MOSIX
+extern kmem_cache_t 	*shm_page_cachep;
+#endif /* CONFIG_MOSIX */

  #endif	/* __KERNEL__ */

diff -Naur linux-2.4.26-om1/ipc/shm.c linux-2.4.26-om1-o/ipc/shm.c
--- linux-2.4.26-om1/ipc/shm.c	2006-05-08 15:03:24.000000000 +0530
+++ linux-2.4.26-om1-o/ipc/shm.c	2006-05-07 17:56:02.000000000 +0530
@@ -683,17 +683,17 @@
  	struct vm_area_struct *shmd, *shmdnext;
  	int retval = -EINVAL;

-#ifdef CONFIG_MOSIX
-	if(current->mosix.dflags & DDEPUTY)
-		return(0);
-	mosix_rebuild_file_list();
-#endif /* CONFIG_MOSIX */
  	down_write(&mm->mmap_sem);
  	for (shmd = mm->mmap; shmd; shmd = shmdnext) {
  		shmdnext = shmd->vm_next;
  		if (shmd->vm_ops == &shm_vm_ops
  		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) ==
(ulong) shmaddr) {
-			do_munmap(mm, shmd->vm_start, shmd->vm_end -
shmd->vm_start);
+#ifdef CONFIG_MOSIX
+			if(current->mosix.dflags & DDEPUTY)
+	              		deputy_munmap(shmd->vm_start,shmd->vm_end -
shmd->vm_start);
+			else 
+#endif /* CONFIG_MOSIX */
+				do_munmap(mm, shmd->vm_start, shmd->vm_end -
shmd->vm_start);
  			retval = 0;
  		}
  	}
diff -Naur linux-2.4.26-om1/ipc/shm.c.orig linux-2.4.26-om1-o/ipc/shm.c.orig
--- linux-2.4.26-om1/ipc/shm.c.orig	1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/ipc/shm.c.orig	2006-05-07 17:47:21.000000000 +0530
@@ -0,0 +1,764 @@
+/*
+ * linux/ipc/shm.c
+ * Copyright (C) 1992, 1993 Krishna Balasubramanian
+ *	 Many improvements/fixes by Bruno Haible.
+ * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994.
+ * Fixed the shm swap deallocation (shm_unuse()), August 1998 Andrea
Arcangeli.
+ *
+ * /proc/sysvipc/shm support (c) 1999 Dragos Acostachioaie
<[email protected]>
+ * BIGMEM support, Andrea Arcangeli <[email protected]>
+ * SMP thread shm, Jean-Luc Boyard <[email protected]>
+ * HIGHMEM support, Ingo Molnar <[email protected]>
+ * Make shmmax, shmall, shmmni sysctl'able, Christoph Rohland <[email protected]>
+ * Shared /dev/zero support, Kanoj Sarcar <kanoj-sJ/[email protected]>
+ * Move the mm functionality over to mm/shmem.c, Christoph Rohland
<[email protected]>
+ * 
+ * Some changes by Moshe Bar to eliminate fh leaking problem in openMosix
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/init.h>
+#include <linux/file.h>
+#include <linux/mman.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <linux/hpc.h>
+#include "util.h"
+
+struct shmid_kernel /* private to the kernel */
+{ 
+	struct kern_ipc_perm	shm_perm;
+	struct file *		shm_file;
+	int			id;
+	unsigned long		shm_nattch;
+	unsigned long		shm_segsz;
+	time_t			shm_atim;
+	time_t			shm_dtim;
+	time_t			shm_ctim;
+	pid_t			shm_cprid;
+	pid_t			shm_lprid;
+};
+
+#define shm_flags	shm_perm.mode
+
+static struct file_operations shm_file_operations;
+static struct vm_operations_struct shm_vm_ops;
+
+static struct ipc_ids shm_ids;
+
+#define shm_lock(id)	((struct shmid_kernel*)ipc_lock(&shm_ids,id))
+#define shm_unlock(id)	ipc_unlock(&shm_ids,id)
+#define shm_lockall()	ipc_lockall(&shm_ids)
+#define shm_unlockall()	ipc_unlockall(&shm_ids)
+#define shm_get(id)	((struct shmid_kernel*)ipc_get(&shm_ids,id))
+#define shm_buildid(id, seq) \
+	ipc_buildid(&shm_ids, id, seq)
+
+static int newseg (key_t key, int shmflg, size_t size);
+static void shm_open (struct vm_area_struct *shmd);
+static void shm_close (struct vm_area_struct *shmd);
+#ifdef CONFIG_PROC_FS
+static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset,
int length, int *eof, void *data);
+#endif
+
+size_t	shm_ctlmax = SHMMAX;
+size_t 	shm_ctlall = SHMALL;
+int 	shm_ctlmni = SHMMNI;
+
+static int shm_tot; /* total number of shared memory pages */
+
+void __init shm_init (void)
+{
+	ipc_init_ids(&shm_ids, 1);
+#ifdef CONFIG_PROC_FS
+	create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc,
NULL);
+#endif
+}
+
+static inline int shm_checkid(struct shmid_kernel *s, int id)
+{
+	if (ipc_checkid(&shm_ids,&s->shm_perm,id))
+		return -EIDRM;
+	return 0;
+}
+
+static inline struct shmid_kernel *shm_rmid(int id)
+{
+	return (struct shmid_kernel *)ipc_rmid(&shm_ids,id);
+}
+
+static inline int shm_addid(struct shmid_kernel *shp)
+{
+	return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni+1);
+}
+
+
+
+static inline void shm_inc (int id) {
+	struct shmid_kernel *shp;
+
+	if(!(shp = shm_lock(id)))
+		BUG();
+	shp->shm_atim = CURRENT_TIME;
+	shp->shm_lprid = current->pid;
+	shp->shm_nattch++;
+	shm_unlock(id);
+}
+
+/* This is called by fork, once for every shm attach. */
+static void shm_open (struct vm_area_struct *shmd)
+{
+	shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
+}
+
+/*
+ * shm_destroy - free the struct shmid_kernel
+ *
+ * @shp: struct to free
+ *
+ * It has to be called with shp and shm_ids.sem locked,
+ * but returns with shp unlocked and freed.
+ */
+static void shm_destroy (struct shmid_kernel *shp)
+{
+	shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	shm_rmid (shp->id);
+	shm_unlock(shp->id);
+	shmem_lock(shp->shm_file, 0);
+	fput (shp->shm_file);
+	kfree (shp);
+}
+
+/*
+ * remove the attach descriptor shmd.
+ * free memory for segment if it is marked destroyed.
+ * The descriptor has already been removed from the current->mm->mmap list
+ * and will later be kfree()d.
+ */
+static void shm_close (struct vm_area_struct *shmd)
+{
+	struct file * file = shmd->vm_file;
+	int id = file->f_dentry->d_inode->i_ino;
+	struct shmid_kernel *shp;
+
+	down (&shm_ids.sem);
+	/* remove from the list of attaches of the shm segment */
+	if(!(shp = shm_lock(id)))
+		BUG();
+	shp->shm_lprid = current->pid;
+	shp->shm_dtim = CURRENT_TIME;
+	shp->shm_nattch--;
+	if(shp->shm_nattch == 0 &&
+	   shp->shm_flags & SHM_DEST)
+		shm_destroy (shp);
+	else
+		shm_unlock(id);
+	up (&shm_ids.sem);
+}
+
+static int shm_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	UPDATE_ATIME(file->f_dentry->d_inode);
+	vma->vm_ops = &shm_vm_ops;
+	shm_inc(file->f_dentry->d_inode->i_ino);
+	return 0;
+}
+
+static struct file_operations shm_file_operations = {
+	mmap:	shm_mmap
+};
+
+static struct vm_operations_struct shm_vm_ops = {
+	open:	shm_open,	/* callback for a new vm-area open */
+	close:	shm_close,	/* callback for when the vm-area is released
*/
+	nopage:	shmem_nopage,
+};
+
+static int newseg (key_t key, int shmflg, size_t size)
+{
+	int error;
+	struct shmid_kernel *shp;
+	int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
+	struct file * file;
+	char name[13];
+	int id;
+
+	if (size < SHMMIN || size > shm_ctlmax)
+		return -EINVAL;
+
+	if (shm_tot + numpages >= shm_ctlall)
+		return -ENOSPC;
+
+	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_USER);
+	if (!shp)
+		return -ENOMEM;
+	sprintf (name, "SYSV%08x", key);
+	file = shmem_file_setup(name, size);
+	error = PTR_ERR(file);
+	if (IS_ERR(file))
+		goto no_file;
+
+	error = -ENOSPC;
+	id = shm_addid(shp);
+	if(id == -1) 
+		goto no_id;
+	shp->shm_perm.key = key;
+	shp->shm_flags = (shmflg & S_IRWXUGO);
+	shp->shm_cprid = current->pid;
+	shp->shm_lprid = 0;
+	shp->shm_atim = shp->shm_dtim = 0;
+	shp->shm_ctim = CURRENT_TIME;
+	shp->shm_segsz = size;
+	shp->shm_nattch = 0;
+	shp->id = shm_buildid(id,shp->shm_perm.seq);
+	shp->shm_file = file;
+	file->f_dentry->d_inode->i_ino = shp->id;
+	file->f_op = &shm_file_operations;
+	shm_tot += numpages;
+	shm_unlock (id);
+	return shp->id;
+
+no_id:
+	fput(file);
+no_file:
+	kfree(shp);
+	return error;
+}
+
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+{
+	struct shmid_kernel *shp;
+	int err, id = 0;
+
+	down(&shm_ids.sem);
+	if (key == IPC_PRIVATE) {
+		err = newseg(key, shmflg, size);
+	} else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
+		if (!(shmflg & IPC_CREAT))
+			err = -ENOENT;
+		else
+			err = newseg(key, shmflg, size);
+	} else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
+		err = -EEXIST;
+	} else {
+		shp = shm_lock(id);
+		if(shp==NULL)
+			BUG();
+		if (shp->shm_segsz < size)
+			err = -EINVAL;
+		else if (ipcperms(&shp->shm_perm, shmflg))
+			err = -EACCES;
+		else
+			err = shm_buildid(id, shp->shm_perm.seq);
+		shm_unlock(id);
+	}
+	up(&shm_ids.sem);
+	return err;
+}
+
+static inline unsigned long copy_shmid_to_user(void *buf, struct shmid64_ds
*in, int version)
+{
+	switch(version) {
+	case IPC_64:
+		return copy_to_user(buf, in, sizeof(*in));
+	case IPC_OLD:
+	    {
+		struct shmid_ds out;
+
+		ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm);
+		out.shm_segsz	= in->shm_segsz;
+		out.shm_atime	= in->shm_atime;
+		out.shm_dtime	= in->shm_dtime;
+		out.shm_ctime	= in->shm_ctime;
+		out.shm_cpid	= in->shm_cpid;
+		out.shm_lpid	= in->shm_lpid;
+		out.shm_nattch	= in->shm_nattch;
+
+		return copy_to_user(buf, &out, sizeof(out));
+	    }
+	default:
+		return -EINVAL;
+	}
+}
+
+struct shm_setbuf {
+	uid_t	uid;
+	gid_t	gid;
+	mode_t	mode;
+}; 
+
+static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out,
void *buf, int version)
+{
+	switch(version) {
+	case IPC_64:
+	    {
+		struct shmid64_ds tbuf;
+
+		if (copy_from_user(&tbuf, buf, sizeof(tbuf)))
+			return -EFAULT;
+
+		out->uid	= tbuf.shm_perm.uid;
+		out->gid	= tbuf.shm_perm.gid;
+		out->mode	= tbuf.shm_flags;
+
+		return 0;
+	    }
+	case IPC_OLD:
+	    {
+		struct shmid_ds tbuf_old;
+
+		if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
+			return -EFAULT;
+
+		out->uid	= tbuf_old.shm_perm.uid;
+		out->gid	= tbuf_old.shm_perm.gid;
+		out->mode	= tbuf_old.shm_flags;
+
+		return 0;
+	    }
+	default:
+		return -EINVAL;
+	}
+}
+
+static inline unsigned long copy_shminfo_to_user(void *buf, struct
shminfo64 *in, int version)
+{
+	switch(version) {
+	case IPC_64:
+		return copy_to_user(buf, in, sizeof(*in));
+	case IPC_OLD:
+	    {
+		struct shminfo out;
+
+		if(in->shmmax > INT_MAX)
+			out.shmmax = INT_MAX;
+		else
+			out.shmmax = (int)in->shmmax;
+
+		out.shmmin	= in->shmmin;
+		out.shmmni	= in->shmmni;
+		out.shmseg	= in->shmseg;
+		out.shmall	= in->shmall; 
+
+		return copy_to_user(buf, &out, sizeof(out));
+	    }
+	default:
+		return -EINVAL;
+	}
+}
+
+static void shm_get_stat (unsigned long *rss, unsigned long *swp) 
+{
+	struct shmem_inode_info *info;
+	int i;
+
+	*rss = 0;
+	*swp = 0;
+
+	for(i = 0; i <= shm_ids.max_id; i++) {
+		struct shmid_kernel* shp;
+		struct inode * inode;
+
+		shp = shm_get(i);
+		if(shp == NULL)
+			continue;
+		inode = shp->shm_file->f_dentry->d_inode;
+		info = SHMEM_I(inode);
+		spin_lock (&info->lock);
+		*rss += inode->i_mapping->nrpages;
+		*swp += info->swapped;
+		spin_unlock (&info->lock);
+	}
+}
+
+asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+	struct shm_setbuf setbuf;
+	struct shmid_kernel *shp;
+	int err, version;
+
+	if (cmd < 0 || shmid < 0)
+		return -EINVAL;
+
+	version = ipc_parse_version(&cmd);
+
+	switch (cmd) { /* replace with proc interface ? */
+	case IPC_INFO:
+	{
+		struct shminfo64 shminfo;
+
+		memset(&shminfo,0,sizeof(shminfo));
+		shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
+		shminfo.shmmax = shm_ctlmax;
+		shminfo.shmall = shm_ctlall;
+
+		shminfo.shmmin = SHMMIN;
+		if(copy_shminfo_to_user (buf, &shminfo, version))
+			return -EFAULT;
+		/* reading a integer is always atomic */
+		err= shm_ids.max_id;
+		if(err<0)
+			err = 0;
+		return err;
+	}
+	case SHM_INFO:
+	{
+		struct shm_info shm_info;
+
+		memset(&shm_info,0,sizeof(shm_info));
+		down(&shm_ids.sem);
+		shm_lockall();
+		shm_info.used_ids = shm_ids.in_use;
+		shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
+		shm_info.shm_tot = shm_tot;
+		shm_info.swap_attempts = 0;
+		shm_info.swap_successes = 0;
+		err = shm_ids.max_id;
+		shm_unlockall();
+		up(&shm_ids.sem);
+		if(copy_to_user (buf, &shm_info, sizeof(shm_info)))
+			return -EFAULT;
+
+		return err < 0 ? 0 : err;
+	}
+	case SHM_STAT:
+	case IPC_STAT:
+	{
+		struct shmid64_ds tbuf;
+		int result;
+		memset(&tbuf, 0, sizeof(tbuf));
+		shp = shm_lock(shmid);
+		if(shp==NULL)
+			return -EINVAL;
+		if(cmd==SHM_STAT) {
+			err = -EINVAL;
+			if (shmid > shm_ids.max_id)
+				goto out_unlock;
+			result = shm_buildid(shmid, shp->shm_perm.seq);
+		} else {
+			err = shm_checkid(shp,shmid);
+			if(err)
+				goto out_unlock;
+			result = 0;
+		}
+		err=-EACCES;
+		if (ipcperms (&shp->shm_perm, S_IRUGO))
+			goto out_unlock;
+		kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
+		tbuf.shm_segsz	= shp->shm_segsz;
+		tbuf.shm_atime	= shp->shm_atim;
+		tbuf.shm_dtime	= shp->shm_dtim;
+		tbuf.shm_ctime	= shp->shm_ctim;
+		tbuf.shm_cpid	= shp->shm_cprid;
+		tbuf.shm_lpid	= shp->shm_lprid;
+		tbuf.shm_nattch	= shp->shm_nattch;
+		shm_unlock(shmid);
+		if(copy_shmid_to_user (buf, &tbuf, version))
+			return -EFAULT;
+		return result;
+	}
+	case SHM_LOCK:
+	case SHM_UNLOCK:
+	{
+/* Allow superuser to lock segment in memory */
+/* Should the pages be faulted in here or leave it to user? */
+/* need to determine interaction with current->swappable */
+		if (!capable(CAP_IPC_LOCK))
+			return -EPERM;
+
+		shp = shm_lock(shmid);
+		if(shp==NULL)
+			return -EINVAL;
+		err = shm_checkid(shp,shmid);
+		if(err)
+			goto out_unlock;
+		if(cmd==SHM_LOCK) {
+			shmem_lock(shp->shm_file, 1);
+			shp->shm_flags |= SHM_LOCKED;
+		} else {
+			shmem_lock(shp->shm_file, 0);
+			shp->shm_flags &= ~SHM_LOCKED;
+		}
+		shm_unlock(shmid);
+		return err;
+	}
+	case IPC_RMID:
+	{
+		/*
+		 *	We cannot simply remove the file. The SVID states
+		 *	that the block remains until the last person
+		 *	detaches from it, then is deleted. A shmat() on
+		 *	an RMID segment is legal in older Linux and if 
+		 *	we change it apps break...
+		 *
+		 *	Instead we set a destroyed flag, and then blow
+		 *	the name away when the usage hits zero.
+		 */
+#ifdef CONFIG_MOSIX
+ 		/* mosix_rebuild_file_list();  fh leakage fixed - moshe */
+#endif
+		down(&shm_ids.sem);
+		shp = shm_lock(shmid);
+		err = -EINVAL;
+		if (shp == NULL) 
+			goto out_up;
+		err = shm_checkid(shp, shmid);
+		if(err)
+			goto out_unlock_up;
+		if (current->euid != shp->shm_perm.uid &&
+		    current->euid != shp->shm_perm.cuid && 
+		    !capable(CAP_SYS_ADMIN)) {
+			err=-EPERM;
+			goto out_unlock_up;
+		}
+		if (shp->shm_nattch){
+			shp->shm_flags |= SHM_DEST;
+			/* Do not find it any more */
+			shp->shm_perm.key = IPC_PRIVATE;
+			shm_unlock(shmid);
+		} else
+			shm_destroy (shp);
+		up(&shm_ids.sem);
+		return err;
+	}
+
+	case IPC_SET:
+	{
+		if(copy_shmid_from_user (&setbuf, buf, version))
+			return -EFAULT;
+		down(&shm_ids.sem);
+		shp = shm_lock(shmid);
+		err=-EINVAL;
+		if(shp==NULL)
+			goto out_up;
+		err = shm_checkid(shp,shmid);
+		if(err)
+			goto out_unlock_up;
+		err=-EPERM;
+		if (current->euid != shp->shm_perm.uid &&
+		    current->euid != shp->shm_perm.cuid && 
+		    !capable(CAP_SYS_ADMIN)) {
+			goto out_unlock_up;
+		}
+
+		shp->shm_perm.uid = setbuf.uid;
+		shp->shm_perm.gid = setbuf.gid;
+		shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO)
+			| (setbuf.mode & S_IRWXUGO);
+		shp->shm_ctim = CURRENT_TIME;
+		break;
+	}
+
+	default:
+		return -EINVAL;
+	}
+
+	err = 0;
+out_unlock_up:
+	shm_unlock(shmid);
+out_up:
+	up(&shm_ids.sem);
+	return err;
+out_unlock:
+	shm_unlock(shmid);
+	return err;
+}
+
+/*
+ * Fix shmaddr, allocate descriptor, map shm, add attach descriptor to
lists.
+ */
+asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong
*raddr)
+{
+	struct shmid_kernel *shp;
+	unsigned long addr;
+	unsigned long size;
+	struct file * file;
+	int    err;
+	unsigned long flags;
+	unsigned long prot;
+	unsigned long o_flags;
+	int acc_mode;
+	void *user_addr;
+
+	if (shmid < 0)
+		return -EINVAL;
+
+	if ((addr = (ulong)shmaddr)) {
+		if (addr & (SHMLBA-1)) {
+			if (shmflg & SHM_RND)
+				addr &= ~(SHMLBA-1);	   /* round down */
+			else
+				return -EINVAL;
+		}
+		flags = MAP_SHARED | MAP_FIXED;
+	} else {
+		if ((shmflg & SHM_REMAP))
+			return -EINVAL;
+
+		flags = MAP_SHARED;
+	}
+
+	if (shmflg & SHM_RDONLY) {
+		prot = PROT_READ;
+		o_flags = O_RDONLY;
+		acc_mode = S_IRUGO;
+	} else {
+		prot = PROT_READ | PROT_WRITE;
+		o_flags = O_RDWR;
+		acc_mode = S_IRUGO | S_IWUGO;
+	}
+
+	/*
+	 * We cannot rely on the fs check since SYSV IPC does have an
+	 * additional creator id...
+	 */
+	shp = shm_lock(shmid);
+	if(shp == NULL)
+		return -EINVAL;
+	err = shm_checkid(shp,shmid);
+	if (err) {
+		shm_unlock(shmid);
+		return err;
+	}
+	if (ipcperms(&shp->shm_perm, acc_mode)) {
+		shm_unlock(shmid);
+		return -EACCES;
+	}
+	file = shp->shm_file;
+	size = file->f_dentry->d_inode->i_size;
+	shp->shm_nattch++;
+	shm_unlock(shmid);
+
+#ifdef CONFIG_MOSIX
+	user_addr = (void *) do_mmap_down (file, addr, size, prot, flags,
0);
+#else
+	down_write(&current->mm->mmap_sem);
+	if (addr && !(shmflg & SHM_REMAP)) {
+		user_addr = ERR_PTR(-EINVAL);
+		if (find_vma_intersection(current->mm, addr, addr + size))
+			goto invalid;
+		/*
+		 * If shm segment goes below stack, make sure there is some
+		 * space left for the stack to grow (at least 4 pages).
+		 */
+		if (addr < current->mm->start_stack &&
+		    addr > current->mm->start_stack - size - PAGE_SIZE * 5)
+			goto invalid;
+	}
+ 
+	user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
+
+invalid:
+	up_write(&current->mm->mmap_sem);
+#endif /* CONFIG_MOSIX */
+
+	down (&shm_ids.sem);
+	if(!(shp = shm_lock(shmid)))
+		BUG();
+	shp->shm_nattch--;
+	if(shp->shm_nattch == 0 &&
+	   shp->shm_flags & SHM_DEST)
+		shm_destroy (shp);
+	else
+		shm_unlock(shmid);
+	up (&shm_ids.sem);
+
+	*raddr = (unsigned long) user_addr;
+	err = 0;
+	if (IS_ERR(user_addr))
+		err = PTR_ERR(user_addr);
+	return err;
+
+}
+
+/*
+ * detach and kill segment if marked destroyed.
+ * The work is done in shm_close.
+ */
+asmlinkage long sys_shmdt (char *shmaddr)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *shmd, *shmdnext;
+	int retval = -EINVAL;
+
+	down_write(&mm->mmap_sem);
+	for (shmd = mm->mmap; shmd; shmd = shmdnext) {
+		shmdnext = shmd->vm_next;
+		if (shmd->vm_ops == &shm_vm_ops
+		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) ==
(ulong) shmaddr) {
+#ifdef CONFIG_MOSIX
+			if(current->mosix.dflags & DDEPUTY)
+	              		deputy_munmap(shmd->vm_start,shmd->vm_end -
shmd->vm_start);
+			else 
+#endif /* CONFIG_MOSIX */
+				do_munmap(mm, shmd->vm_start, shmd->vm_end -
shmd->vm_start);
+			retval = 0;
+		}
+	}
+	up_write(&mm->mmap_sem);
+	return retval;
+}
+
+#ifdef CONFIG_PROC_FS
+static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset,
int length, int *eof, void *data)
+{
+	off_t pos = 0;
+	off_t begin = 0;
+	int i, len = 0;
+
+	down(&shm_ids.sem);
+	len += sprintf(buffer, "       key      shmid perms       size  cpid
lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n");
+
+	for(i = 0; i <= shm_ids.max_id; i++) {
+		struct shmid_kernel* shp;
+
+		shp = shm_lock(i);
+		if(shp!=NULL) {
+#define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u
%10lu %10lu %10lu\n"
+#define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u
%10lu %10lu %10lu\n"
+			char *format;
+
+			if (sizeof(size_t) <= sizeof(int))
+				format = SMALL_STRING;
+			else
+				format = BIG_STRING;
+			len += sprintf(buffer + len, format,
+				shp->shm_perm.key,
+				shm_buildid(i, shp->shm_perm.seq),
+				shp->shm_flags,
+				shp->shm_segsz,
+				shp->shm_cprid,
+				shp->shm_lprid,
+				shp->shm_nattch,
+				shp->shm_perm.uid,
+				shp->shm_perm.gid,
+				shp->shm_perm.cuid,
+				shp->shm_perm.cgid,
+				shp->shm_atim,
+				shp->shm_dtim,
+				shp->shm_ctim);
+			shm_unlock(i);
+
+			pos += len;
+			if(pos < offset) {
+				len = 0;
+				begin = pos;
+			}
+			if(pos > offset + length)
+				goto done;
+		}
+	}
+	*eof = 1;
+done:
+	up(&shm_ids.sem);
+	*start = buffer + (offset - begin);
+	len -= (offset - begin);
+	if(len > length)
+		len = length;
+	if(len < 0)
+		len = 0;
+	return len;
+}
+#endif
diff -Naur linux-2.4.26-om1/kernel/fork.c linux-2.4.26-om1-o/kernel/fork.c
--- linux-2.4.26-om1/kernel/fork.c	2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/kernel/fork.c	2006-05-07 17:56:02.000000000 +0530
@@ -32,6 +32,7 @@

  #ifdef CONFIG_MOSIX
  #include <linux/hpc.h>
+#include<hpc/mig_shm.h>
  #endif /* CONFIG_MOSIX */

  /* The idle threads do not count.. */
@@ -1014,6 +1015,11 @@

  /* SLAB cache for mm_struct structures (tsk->mm) */
  kmem_cache_t *mm_cachep;
+kmem_cache_t *shm_pgentry_cachep;
+
+#ifdef CONFIG_MOSIX
+kmem_cache_t *shm_page_cachep;
+#endif /* CONFIG_MOSIX */

  void __init proc_caches_init(void)
  {
@@ -1046,4 +1052,15 @@
  			SLAB_HWCACHE_ALIGN, NULL, NULL);
  	if(!mm_cachep)
  		panic("vma_init: Cannot alloc mm_struct SLAB cache");
+
+#ifdef CONFIG_MOSIX 
+
+	shm_page_cachep = kmem_cache_create("shm_page",
+                        sizeof(struct shm_page), 0,
+                        SLAB_HWCACHE_ALIGN, NULL, NULL);
+        if(!shm_page_cachep)
+                panic("Cannot alloc shm_page SLAB cache");
+
+#endif /* CONFIG_MOSIX */
+
  }
diff -Naur linux-2.4.26-om1/mm/filemap.c linux-2.4.26-om1-o/mm/filemap.c
--- linux-2.4.26-om1/mm/filemap.c	2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/filemap.c	2006-05-07 17:56:02.000000000 +0530
@@ -32,6 +32,8 @@

  #ifdef CONFIG_MOSIX
  #include <linux/hpc.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
  #endif /* CONFIG_MOSIX */
  #ifdef CONFIG_MOSIX_DFSA
  #include <linux/dfsa_interface.h>
@@ -764,8 +766,8 @@
   * This adds the requested page to the page cache if it isn't already
there,
   * and schedules an I/O to read in its contents from disk.
   */
-static int FASTCALL(page_cache_read(struct file * file, unsigned long
offset));
-static int page_cache_read(struct file * file, unsigned long offset)
+static int FASTCALL(page_cache_read(struct file * file, unsigned long
offset,unsigned long unused));
+static int page_cache_read(struct file * file, unsigned long
offset,unsigned long unused)
  {
  	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
  	struct page **hash = page_hash(mapping, offset);
@@ -782,6 +784,12 @@
  		return -ENOMEM;

  	if (!add_to_page_cache_unique(page, mapping, offset, hash)) {
+#ifdef CONFIG_MOSIX
+		if(current->mosix.dflags & DREMOTE) {
+			page->shm_page =
find_get_shm_page(mapping,offset,shm_page_hash(mapping,offset));
+			(page->shm_page)->state |= unused;
+		}
+#endif /* CONFIG_MOSIX */
  		int error = mapping->a_ops->readpage(file, page);
  		page_cache_release(page);
  		return error;
@@ -807,7 +815,7 @@

  	offset = CLUSTER_OFFSET(offset);
  	while ((pages-- > 0) && (offset < filesize)) {
-		int error = page_cache_read(file, offset);
+		int error = page_cache_read(file, offset,0);
  		if (error < 0)
  			return error;
  		offset ++;
@@ -1359,7 +1367,7 @@

  		if (ra_index >= end_index)
  			break;
-		if (page_cache_read(filp, ra_index) < 0)
+		if (page_cache_read(filp, ra_index,0) < 0)
  			break;

  		ahead++;
@@ -1985,7 +1993,7 @@
  		nr = max;

  	while (nr) {
-		page_cache_read(file, index);
+		page_cache_read(file, index,0);
  		index++;
  		nr--;
  	}
@@ -2081,23 +2089,20 @@
  	struct inode *inode = mapping->host;
  	struct page *page, **hash;
  	unsigned long size, pgoff, endoff;
-
  	pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) +
area->vm_pgoff;
  	endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT) +
area->vm_pgoff;
-
+
  retry_all:
  	/*
  	 * An external ptracer can access pages that normally aren't
  	 * accessible..
  	 */
  	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	if ((pgoff >= size) && (area->vm_mm == current->mm))
+	if ((area->vm_mm == current->mm) && (pgoff >= size))
  		return NULL;
-
  	/* The "size" of the file, as far as mmap is concerned, isn't bigger
than the mapping */
  	if (size > endoff)
  		size = endoff;
-
  	/*
  	 * Do we have something in the page cache already?
  	 */
@@ -2111,22 +2116,29 @@
  	 * Ok, found a page in the page cache, now we need to check
  	 * that it's up-to-date.
  	 */
-	if (!Page_Uptodate(page))
+ 
+
+	if (!Page_Uptodate(page))
  		goto page_not_uptodate;

+
  success:
   	/*
  	 * Try read-ahead for sequential areas.
  	 */
-	if (VM_SequentialReadHint(area))
-		nopage_sequential_readahead(area, pgoff, size);
-
+	if(!(current->mosix.dflags&DREMOTE)) {
+		if (VM_SequentialReadHint(area))
+			nopage_sequential_readahead(area, pgoff, size);
+	}
  	/*
  	 * Found the page and have a reference on it, need to check sharing
  	 * and possibly copy it over to another page..
  	 */
  	mark_page_accessed(page);
  	flush_page_to_ram(page);
+
+ 
+
  	return page;

  no_cached_page:
@@ -2137,17 +2149,17 @@
  	 * Otherwise, we're off the end of a privately mapped file,
  	 * so we need to map a zero page.
  	 */
-	if ((pgoff < size) && !VM_RandomReadHint(area))
+	if ((pgoff < size) &&
!VM_RandomReadHint(area)&&!(current->mosix.dflags&DREMOTE))
  		error = read_cluster_nonblocking(file, pgoff, size);
  	else
-		error = page_cache_read(file, pgoff);
+		error = page_cache_read(file, pgoff,unused);

  	/*
  	 * The page we want has now been added to the page cache.
  	 * In the unlikely event that someone removed it in the
  	 * meantime, we'll just come back here and read it again.
  	 */
-	if (error >= 0)
+	if (error >= 0)
  		goto retry_find;

  	/*
@@ -2155,11 +2167,19 @@
  	 * system is low on memory, or a problem occurs while trying
  	 * to schedule I/O.
  	 */
+
+#ifdef CONFIG_MOSIX
+	if(error == -EBUSY) 
+              	return PAGE_BUSY; 
+#endif /* CONFIG_MOSIX */
+
  	if (error == -ENOMEM)
  		return NOPAGE_OOM;
  	return NULL;

  page_not_uptodate:
+ 
+
  	lock_page(page);

  	/* Did it get unhashed while we waited for it? */
@@ -2174,12 +2194,35 @@
  		UnlockPage(page);
  		goto success;
  	}
+#ifdef CONFIG_MOSIX
+	if(current->mosix.dflags & DREMOTE) {
+		page->shm_page =
find_get_shm_page(mapping,pgoff,shm_page_hash(mapping,pgoff));
+		(page->shm_page)->state |= unused;
+	}
+#endif /* CONFIG_MOSIX */

-	if (!mapping->a_ops->readpage(file, page)) {
+	if (!(error = mapping->a_ops->readpage(file, page))) {
  		wait_on_page(page);
  		if (Page_Uptodate(page))
  			goto success;
+#ifdef CONFIG_MOSIX
+		else  if(current->mosix.dflags & DREMOTE)  {
+			page_cache_release(page);
+			return PAGE_BUSY;
+		}
+#endif /* CONFIG_MOSIX */
+	}
+#ifdef CONFIG_MOSIX 
+	else if(current->mosix.dflags & DREMOTE)  {
+		page_cache_release(page);
+		if(error == -EBUSY) 
+                        return PAGE_BUSY;
+		else if(error == -ENOMEM)
+			return NOPAGE_OOM;
+		else
+			return NULL;
  	}
+#endif /* CONFIG_MOSIX */

  	/*
  	 * Umm, take care of errors if the page isn't up-to-date.
@@ -2187,6 +2230,7 @@
  	 * because there really aren't any performance issues here
  	 * and we need to check for errors.
  	 */
+
  	lock_page(page);

  	/* Somebody truncated the page on us? */
@@ -2202,11 +2246,12 @@
  		goto success;
  	}
  	ClearPageError(page);
-	if (!mapping->a_ops->readpage(file, page)) {
+ 
+	if (!(mapping->a_ops->readpage(file, page))) {
  		wait_on_page(page);
  		if (Page_Uptodate(page))
  			goto success;
-	}
+	}

  	/*
  	 * Things didn't work out. Return zero to tell the
@@ -2643,7 +2688,7 @@
  		}
  	} else {
  		while ((start < end) && (start < size)) {
-			error = page_cache_read(file, start);
+			error = page_cache_read(file, start,0);
  			start++;
  			if (error < 0)
  				break;
@@ -2754,6 +2799,9 @@
  	int unmapped_error = 0;
  	int error = -EINVAL;

+	if(current->mosix.dflags & DREMOTE)
+		return 0;
+
  	down_write(&current->mm->mmap_sem);

  	if (start & ~PAGE_MASK)
@@ -3423,10 +3471,32 @@
  		page_hash_table = (struct page **)
  			__get_free_pages(GFP_ATOMIC, order);
  	} while(page_hash_table == NULL && --order > 0);
+ 
+	htable_size = mempages;
+        htable_size *= sizeof(struct shm_page *);
+        for(order = 0; (PAGE_SIZE << order) < htable_size; order++)
+                ;
+
+	do {
+                unsigned long tmp = (PAGE_SIZE << order) / sizeof(struct
page *);
+
+                shm_page_hash_bits = 0;
+                while((tmp >>= 1UL) != 0UL)
+                        shm_page_hash_bits++;
+
+                shm_page_hash_table = (struct shm_page **)
+                        __get_free_pages(GFP_ATOMIC, order);
+        } while(shm_page_hash_table == NULL && --order > 0);
+

  	printk("Page-cache hash table entries: %d (order: %ld, %ld
bytes)\n",
  	       (1 << page_hash_bits), order, (PAGE_SIZE << order));
  	if (!page_hash_table)
  		panic("Failed to allocate page hash table\n");
  	memset((void *)page_hash_table, 0, PAGE_HASH_SIZE * sizeof(struct
page *));
+
+	if (!shm_page_hash_table)
+                panic("Failed to allocate page hash table\n");
+        memset((void *)shm_page_hash_table, 0, SHM_PAGE_HASH_SIZE *
sizeof(struct shm_page *));
+
  }
diff -Naur linux-2.4.26-om1/mm/memory.c linux-2.4.26-om1-o/mm/memory.c
--- linux-2.4.26-om1/mm/memory.c	2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/memory.c	2006-05-07 17:56:02.000000000 +0530
@@ -52,6 +52,8 @@

  #ifdef CONFIG_MOSIX
  #include <linux/hpc.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
  #endif /* CONFIG_MOSIX */

  unsigned long max_mapnr;
@@ -991,12 +993,46 @@
  static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
  	unsigned long address, pte_t *page_table, pte_t pte)
  {
-	struct page *old_page, *new_page;
+	struct page *old_page,*new_page;
+	struct shm_page *shm_page = NULL;

  	old_page = pte_page(pte);
  	if (!VALID_PAGE(old_page))
  		goto bad_wp_page;

+#ifdef CONFIG_MOSIX
+	if(vma->vm_flags & VM_SHARED) {
+
+		spin_unlock(&mm->page_table_lock);
+
+
+		new_page = get_nopage(vma,address,&shm_page,11);
+
+
+		if(shm_page->state & PERM_ERR) {
+			shm_pagecache_release(shm_page);
+			return -1;
+		}
+
+		spin_lock(&shm_page->shm_lock);
+
+		spin_lock(&mm->page_table_lock);
+		if (pte_same(*page_table, pte) && ( shm_page->owner ==0 ||
shm_page->owner == PE) && 
+						((shm_page->state &
STATE_MASK) == EXCLUSIVE) ) 
+                	break_cow(vma,old_page,address,page_table);
+ 
+		spin_unlock(&mm->page_table_lock);
+		spin_unlock(&shm_page->shm_lock);
+ 
+		shm_pagecache_release(shm_page); 
+
+		if(new_page)
+			page_cache_release(new_page);
+
+		return 1;
+	}
+#endif /* CONFIG_MOSIX */
+
  	if (!TryLockPage(old_page)) {
  		int reuse = can_share_swap_page(old_page);
  		unlock_page(old_page);
@@ -1318,32 +1354,47 @@
  {
  	struct page * new_page;
  	pte_t entry;
+#ifdef CONFIG_MOSIX
+	struct shm_page *shm_page = NULL;
+	int ret = 2;
+#endif /* CONFIG_MOSIX */

  	if (!vma->vm_ops || !vma->vm_ops->nopage)
  		return do_anonymous_page(mm, vma, page_table, write_access,
address);
+
  	spin_unlock(&mm->page_table_lock);

-	new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);

+#ifdef CONFIG_MOSIX
+	new_page = get_nopage(vma, address&PAGE_MASK, &shm_page,
+						(!write_access ||
(vma->vm_flags & VM_SHARED)) ? (!(! write_access)) : 2 );
+#else /* CONFIG_MOSIX */
+        new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
+#endif /* CONFIG_MOSIX */
+
  	if (new_page == NULL)	/* no page was available -- SIGBUS */
  		return 0;
+
  	if (new_page == NOPAGE_OOM)
  		return -1;

-	/*
-	 * Should we do an early C-O-W break?
-	 */
  	if (write_access && !(vma->vm_flags & VM_SHARED)) {
-		struct page * page = alloc_page(GFP_HIGHUSER);
-		if (!page) {
-			page_cache_release(new_page);
-			return -1;
-		}
-		copy_user_highpage(page, new_page, address);
-		page_cache_release(new_page);
-		lru_cache_add(page);
-		new_page = page;
-	}
+                 struct page * page = alloc_page(GFP_HIGHUSER);
+                 if (!page) {
+                         page_cache_release(new_page);
+                         return -1;
+                 }
+                 copy_user_highpage(page, new_page, address);
+                 page_cache_release(new_page);
+                 lru_cache_add(page);
+                 new_page = page;
+         }
+
+
+#ifdef CONFIG_MOSIX
+	if(shm_page) 
+		spin_lock(&(shm_page->shm_lock));
+#endif /* CONFIG_MOSIX */

  	spin_lock(&mm->page_table_lock);
  	/*
@@ -1357,26 +1408,59 @@
  	 * handle that later.
  	 */
  	/* Only go through if we didn't race with anybody else... */
+
+
+#ifdef CONFIG_MOSIX
+	if (pte_none(*page_table) && 
+		((!shm_page) || (((shm_page->state & STATE_MASK) ==
EXCLUSIVE && (shm_page->owner == 0 || shm_page->owner == PE)) ||
+                (!write_access && (shm_page->state & STATE_MASK) ==
SHARED))) ) {
+#else
  	if (pte_none(*page_table)) {
+#endif /* CONFIG_MOSIX */
+
+
  		if (!PageReserved(new_page))
  			++mm->rss;
  		flush_page_to_ram(new_page);
  		flush_icache_page(vma, new_page);
  		entry = mk_pte(new_page, vma->vm_page_prot);
-		if (write_access)
+		if (write_access)
  			entry = pte_mkwrite(pte_mkdirty(entry));
+#ifdef CONFIG_MOSIX
+		else
+			entry = pte_wrprotect(entry);
+#endif /* CONFIG_MOSIX */
+
  		set_pte(page_table, entry);
+#ifdef CONFIG_MOSIX 
+		update_mmu_cache(vma,address,entry);
+#endif /* CONFIG_MOSIX */
  	} else {
  		/* One of our sibling threads was faster, back out. */
  		page_cache_release(new_page);
+#ifdef CONFIG_MOSIX
+		ret = 1;
+#else
  		spin_unlock(&mm->page_table_lock);
-		return 1;
+               	return 1;
+#endif /* CONFIG_MOSIX */
+
  	}
+#ifdef CONFIG_MOSIX

-	/* no need to invalidate: a not-present page shouldn't be cached */
+        spin_unlock(&mm->page_table_lock);
+
+	if(shm_page) {
+		spin_unlock(&(shm_page->shm_lock));
+		shm_pagecache_release(shm_page);
+	}
+
+        return ret;       /* Major fault */
+#else
  	update_mmu_cache(vma, address, entry);
-	spin_unlock(&mm->page_table_lock);
-	return 2;	/* Major fault */
+        spin_unlock(&mm->page_table_lock);
+        return 2;       /* Major fault */
+#endif /* CONFIG_MOSIX */
  }

  /*
diff -Naur linux-2.4.26-om1/mm/mmap.c linux-2.4.26-om1-o/mm/mmap.c
--- linux-2.4.26-om1/mm/mmap.c	2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/mmap.c	2006-05-07 17:56:02.000000000 +0530
@@ -27,6 +27,7 @@

  #ifdef CONFIG_MOSIX
  #include <linux/hpc.h>
+extern struct page *shm_nopage(struct vm_area_struct *vma, unsigned long
address, int unused);
  #endif /* CONFIG_MOSIX */
  #ifdef CONFIG_MOSIX_DFSA
  #include <linux/dfsa_interface.h>
@@ -108,26 +109,11 @@

  	if (file) {
  		struct inode *inode = file->f_dentry->d_inode;
-#ifdef CONFIG_MOSIX
-		int was_shared = (inode->i_mapping->i_mmap_shared != NULL);
-#endif /* CONFIG_MOSIX */
  		if (vma->vm_flags & VM_DENYWRITE)
  			atomic_inc(&inode->i_writecount);
  		if(vma->vm_next_share)
  			vma->vm_next_share->vm_pprev_share =
vma->vm_pprev_share;
  		*vma->vm_pprev_share = vma->vm_next_share;
-#ifdef CONFIG_MOSIX
-		if(was_shared && !inode->i_mapping->i_mmap_shared)
-			mosix_no_longer_monkey(inode);
-		if(current->mosix.dflags & DREMOTE)
-		{
-			spin_lock_irq(&current->sigmask_lock);
-			current->mosix.asig |= (1 <<
(REMOTE_FILE_RELEASED-1));
-			spin_unlock_irq(&current->sigmask_lock);
-		}
-		else
-			tell_process(current, DREQ_FILEUNMAP);
-#endif /* CONFIG_MOSIX */
  	}
  #ifdef CONFIG_MOSIX
  	if(current->mosix.stay & DSTAY_PER_MM)
@@ -190,13 +176,6 @@
  	if (brk <= mm->brk) {
  		if (!do_munmap(mm, newbrk, oldbrk-newbrk))
  			goto set_brk;
-#ifdef CONFIG_MOSIX
-		if(process_told(current, DREQ_FILEUNMAP))
-		{
-			process_ack(current, DREQ_FILEUNMAP);
-			mosix_rebuild_file_list();
-		}
-#endif /* CONFIG_MOSIX */
  		goto out;
  	}

@@ -508,35 +487,29 @@
  	if (file) {
  		switch (flags & MAP_TYPE) {
  		case MAP_SHARED:
-			if ((prot & PROT_WRITE) && !(file->f_mode &
FMODE_WRITE))
+			if ((prot & PROT_WRITE) && !(file->f_mode &
FMODE_WRITE))
  				return -EACCES;

  			/* Make sure we don't allow writing to an
append-only file.. */
-			if (IS_APPEND(file->f_dentry->d_inode) &&
(file->f_mode & FMODE_WRITE))
+			if (IS_APPEND(file->f_dentry->d_inode) &&
(file->f_mode & FMODE_WRITE))
  				return -EACCES;

  			/* make sure there are no mandatory locks on the
file. */
-			if (locks_verify_locked(file->f_dentry->d_inode))
+			if (locks_verify_locked(file->f_dentry->d_inode))
  				return -EAGAIN;

  			vm_flags |= VM_SHARED | VM_MAYSHARE;
  			if (!(file->f_mode & FMODE_WRITE))
  				vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
-#ifdef CONFIG_MOSIX
-			if(file->f_mode & FMODE_WRITE)
-				reason_to_come_back |= DSTAY_FOR_MONKEY;
-#endif /* CONFIG_MOSIX */

  			/* fall through */
  		case MAP_PRIVATE:
  #ifdef CONFIG_MOSIX
-
if(file->f_dentry->d_inode->i_mapping->i_mmap_shared)
-				reason_to_come_back |= DSTAY_FOR_MONKEY;
  			if(S_ISCHR(file->f_dentry->d_inode->i_mode))
  				reason_to_come_back |= DSTAY_FOR_DEV;
  			if (!(current->mosix.dflags & DINCOMING))
  #endif /* CONFIG_MOSIX */
-			if (!(file->f_mode & FMODE_READ))
+			if (!(file->f_mode & FMODE_READ))
  				return -EACCES;
  			break;

@@ -574,20 +547,14 @@
  munmap_back:
  	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
  	if (vma && vma->vm_start < addr + len) {
-		if (do_munmap(mm, addr, len))
+		if (do_munmap(mm, addr, len))
  			return -ENOMEM;
-#ifdef CONFIG_MOSIX
-		if(process_told(current, DREQ_FILEUNMAP)) {
-			process_ack(current, DREQ_FILEUNMAP);
-			mosix_rebuild_file_list();
-		}
-#endif /* CONFIG_MOSIX */
  		goto munmap_back;
  	}

  	/* Check against address space limit. */
  	if ((mm->total_vm << PAGE_SHIFT) + len
-	    > current->rlim[RLIMIT_AS].rlim_cur)
+	    > current->rlim[RLIMIT_AS].rlim_cur)
  		return -ENOMEM;

  	/* Private writable mapping? Check memory availability.. */
@@ -627,18 +594,14 @@
  	vma->vm_raend = 0;

  #ifdef CONFIG_MOSIX
-	if(file && !(current->mosix.dflags & DREMOTE) &&
(registration_result =
-		mosix_register_a_file(file, (flags & MAP_DENYWRITE) != 0)) <
0)
-	{
-		error = registration_result;
-		goto free_vma;
-	}
+ 
+
  	/*
  	 * even if we don't end up mapping locally, perform a dummy mapping,
  	 * only to check for fs-specific errors, so we do not fail if and
when
  	 * we ever come home:
  	 */
-	if(MMAP_REMOTELY)
+	if(MMAP_REMOTELY && (file || !(flags&MAP_SHARED)))
  	{
  		vma->vm_file = file;
  		if(file && (error = file->f_op->mmap(file, vma)))
@@ -647,10 +610,20 @@
  		 * (perhaps we were mapping /proc/nnnn/mem)? */
  		if(!MMAP_REMOTELY)
  			goto again_locally_with_vma;
+
+		if(file)
+			get_file(file);
+
+GO_HERE:
  		addr = mosix_deputy_mmap(file, addr, (flags & MAP_FIXED) !=
0,
  			len, vma->vm_flags, pgoff,
  			file ? file->f_dentry->d_inode->i_size : 0,
-			file ? vma->vm_ops->nopage : NULL);
+			file ? vma->vm_ops->nopage : NULL); 
+
+
+		if(file)
+			fput(file);
+
  		if(IS_ERR((const void *)addr))
  		{
  			error = addr;
@@ -663,35 +636,41 @@
  		/* we did not really want that vma... only to check */
  		kmem_cache_free(vm_area_cachep, vma);
  		/* meanwhile someone else could map the same file shared,
so: */
-		if(file &&
file->f_dentry->d_inode->i_mapping->i_mmap_shared)
+                /*if(file &&
file->f_dentry->d_inode->i_mapping->i_mmap_shared)
  		{
  			if(!mosix_go_home(0))
  				return(-EAGAIN);
-			stay_me_and_my_clones(DSTAY_FOR_MONKEY);
-		}
+		}*/
  		return(addr);
  	}

  #endif /* CONFIG_MOSIX */
-	if (file) {
+	if(file) {
  		error = -EINVAL;
-		if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
+		if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
  			goto free_vma;
  		if (vm_flags & VM_DENYWRITE) {
  			error = deny_write_access(file);
-			if (error)
+			if (error)
  				goto free_vma;
  			correct_wcount = 1;
  		}
  		vma->vm_file = file;
  		get_file(file);
  		error = file->f_op->mmap(file, vma);
-		if (error)
+		if (error)
  			goto unmap_and_free_vma;
  	} else if (flags & MAP_SHARED) {
  		error = shmem_zero_setup(vma);
  		if (error)
  			goto free_vma;
+		file = vma->vm_file;
+		if(MMAP_REMOTELY) {
+			if(vma->vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
+				BUG();
+			vma->vm_flags &=
~(VM_GROWSDOWN|VM_GROWSUP|VM_DENYWRITE);
+			goto GO_HERE;
+		}
  	}

  	/* Can addr have changed??
@@ -737,9 +716,9 @@
  #ifdef CONFIG_MOSIX
  	if(reason_to_come_back)
  		stay_me_and_my_clones(reason_to_come_back);
-	if(file && (vm_flags & VM_SHARED))
-		mosix_bring_monkey_users_back(file->f_dentry->d_inode);
+
  #endif /* CONFIG_MOSIX */
+
  	return addr;

  unmap_and_free_vma:
@@ -752,17 +731,10 @@
  	zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
  free_vma:
  	kmem_cache_free(vm_area_cachep, vma);
-#ifdef CONFIG_MOSIX
-	if(registration_result > 0)
-		mosix_undo_last_file_registration(file,
registration_result);
-#endif /* CONFIG_MOSIX */
  	return error;
  #ifdef CONFIG_MOSIX
  again_locally_with_vma:
  	kmem_cache_free(vm_area_cachep, vma);
-	if(registration_result > 0)
-		mosix_undo_last_file_registration(file,
registration_result);
-	registration_result = 0;
  again_locally:
  	mm = current->mm;
  	reason_to_come_back = 0;
@@ -1200,13 +1172,6 @@
  	down_write(&mm->mmap_sem);
  	ret = do_munmap(mm, addr, len);
  	up_write(&mm->mmap_sem);
-#ifdef CONFIG_MOSIX
-	if(process_told(current, DREQ_FILEUNMAP))
-	{
-		process_ack(current, DREQ_FILEUNMAP);
-		mosix_rebuild_file_list();
-	}
-#endif /* CONFIG_MOSIX */
  	return ret;
  }

diff -Naur linux-2.4.26-om1/mm/mremap.c linux-2.4.26-om1-o/mm/mremap.c
--- linux-2.4.26-om1/mm/mremap.c	2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/mremap.c	2006-05-07 17:56:02.000000000 +0530
@@ -375,12 +375,5 @@
  	down_write(&current->mm->mmap_sem);
  	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
  	up_write(&current->mm->mmap_sem);
-#ifdef CONFIG_MOSIX
-	if(process_told(current, DREQ_FILEUNMAP))
-	{
-		process_ack(current, DREQ_FILEUNMAP);
-		mosix_rebuild_file_list();
-	}
-#endif /* CONFIG_MOSIX */
  	return ret;
  }
diff -Naur linux-2.4.26-om1/mm/vmscan.c linux-2.4.26-om1-o/mm/vmscan.c
--- linux-2.4.26-om1/mm/vmscan.c	2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/vmscan.c	2006-05-07 17:56:02.000000000 +0530
@@ -25,6 +25,8 @@
  #include <linux/file.h>

  #include <asm/pgalloc.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>

  /*
   * "vm_passes" is the number of vm passes before failing the
@@ -680,6 +682,25 @@
  	zonelist_t *zonelist;
  	unsigned long pf_free_pages;
  	int error = 0;
+	struct list_head *entry;
+
+#ifdef CONFIG_MOSIX
+
+again:	spin_lock(&shm_pagecache_lock);
+
+        entry = shm_page_unused_list.prev;
+        if(entry != &shm_page_unused_list) {
+                struct shm_page *shm_page;
+                shm_page = list_entry(entry,struct shm_page,list);
+		list_del(&shm_page->list);
+		spin_unlock(&shm_pagecache_lock);
+		kmem_cache_free(shm_page_cachep,shm_page);
+		goto again;
+        }
+
+        spin_unlock(&shm_pagecache_lock);
+
+#endif /* CONFIG_MOSIX */

  	pf_free_pages = current->flags & PF_FREE_PAGES;
  	current->flags &= ~PF_FREE_PAGES;







-Ratna Manoj Bolla.
  M.Tech 2nd year.
  CSE dept. IIT-Guwahati,INDIA.



-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.