[SSI] openssi/kernel/fs/proc array.c, 1.7, 1.8 base.c, 1.24, 1.25 internal.h, 1.3, 1.4 proc_cluster.c, 1.14, 1.15

Roger Tsang <[email protected]>
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/fs/proc
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv29491/fs/proc

Modified Files:
      Tag: OPENSSI-FC
	array.c base.c internal.h proc_cluster.c 
Log Message:
Bug fixes and enhancements (see ChangeLog)


Index: base.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/base.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- base.c	3 Feb 2009 06:18:13 -0000	1.24
+++ base.c	24 Mar 2009 04:26:29 -0000	1.25
@@ -34,7 +34,6 @@
 #include <linux/ptrace.h>
 #include "internal.h"
 
-
 /*
  * For hysterical raisins we keep the same inumbers as in the old procfs.
  * Feel free to change the macro below - just keep the range distinct from
@@ -234,9 +233,9 @@
 
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
-	struct file *file;
 	struct task_struct *task = proc_task(inode);
 	struct files_struct *files;
+	struct file *file;
 	int fd = proc_type(inode) - PROC_TID_FD_DIR;
 
 	files = get_files_struct(task);
@@ -513,6 +512,7 @@
 	/* 
 	 * FIXME!! SSI_XXX Why do we skip the below proc_check_root ? 
 	 */
+	/* NULL proc_task(inode) when remote */
 	return 0;
 #else
 	return proc_check_root(inode);
@@ -789,6 +789,9 @@
 	return ret;
 }
 
+#define mem_write NULL
+
+#ifndef mem_write
 /* This is a security hazard */
 static ssize_t mem_write(struct file * file, const char * buf,
 			 size_t count, loff_t *ppos)
@@ -832,6 +835,7 @@
 	free_page((unsigned long) page);
 	return copied;
 }
+#endif
 
 static loff_t mem_lseek(struct file * file, loff_t offset, int orig)
 {
@@ -865,8 +869,13 @@
 {
 	if (!type)
 		return mem_read((struct file *)task, buf, count, pos);
+#ifndef mem_write
 	else
 		return mem_write((struct file *)task, buf, count, pos);
+#else
+	/* SSI_XXX: mem_write() is disabled by default in base */
+	return -EINVAL;
+#endif
 }
 
 static ssize_t ssi_mem_read(struct file * file, char * buf,
@@ -882,6 +891,7 @@
 
 }
 
+#ifndef mem_write
 static ssize_t ssi_mem_write(struct file * file, const char * buf,
 			     size_t count, loff_t *ppos)
 {
@@ -890,10 +900,13 @@
 	return PVPOP_PROCFS_READMAPS(vp, (char *)buf, count, ppos, 1, 1);
 
 }
+#endif
 
 static struct file_operations proc_mem_operations = {
 	.read		= ssi_mem_read,
+#ifndef mem_write
 	.write		= ssi_mem_write,
+#endif
 	.open		= mem_open,
 	.llseek		= mem_lseek,
 };
@@ -1103,7 +1116,7 @@
 
 	if (!tmp)
 		return -ENOMEM;
-
+		
 	inode = dentry->d_inode;
 	path = d_path(dentry, mnt, tmp, PAGE_SIZE);
 #ifdef CONFIG_SSI
@@ -1133,6 +1146,8 @@
 	int error = -EACCES;
 	struct inode *inode = dentry->d_inode;
 
+	/* lock_kernel(); */
+
 	if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
 		goto out;
 
@@ -1142,6 +1157,7 @@
 			dentry->d_name.len, buffer, buflen,
 			NULL, NULL);
 out:
+	/* unlock_kernel(); */
 	return error;
 }
 #else
@@ -1397,9 +1413,13 @@
 	return dumpable;
 }
 
+
 #ifdef CONFIG_SSI
-static struct inode *proc_pid_make_inode(struct super_block * sb,
-		struct task_struct *task, int ino, pid_t pid)
+/* Callers must hold VPROC movement
+ * with the exception of when the pid is migrating in.
+ */
+static struct inode *
+proc_pid_make_inode(struct super_block * sb, struct vproc *vp, int ino, int *tgid)
 #else
 static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
 #endif
@@ -1407,10 +1427,8 @@
 	struct inode * inode;
 	struct proc_inode *ei;
 #ifdef CONFIG_SSI
-	struct vproc *vp;
-	int error = 0;
 	int dumpable, euid, egid;
-	int pid_alive = 0;
+	task_t *task;
 #endif
 
 	/* We need a new inode */
@@ -1418,55 +1436,67 @@
 	inode = new_inode(sb);
 	if (!inode)
 		goto out;
+
 	/* Common stuff */
 	ei = PROC_I(inode);
 
 #ifdef CONFIG_SSI
-	vp = LOCATE_VPROC_PID(pid, "perm proc_pid_make_inode");
+	if (PVP(vp)->pvp_flag & PV_IS_LOCAL) {
 #ifdef VPROC_HOLD_ZERO_GET_TASK
-	if (task && (PVP(task->p_vproc)->pvp_flag & PV_IS_LOCAL)) {
+		task = PVP(vp)->pvp_pproc;
+
+		if (!pid_alive(task))
+			goto out_unlock;
 #else
-	if (task) {
+		task = proc_ssi_task(vp);
+		if (task)
+			goto out_unlock;
+
+		if (!pid_alive(task)) {
+			put_task_struct(task);
+			goto out_unlock;
+		}
 #endif
+
 		euid = task->euid;
 		egid = task->egid;
 		dumpable = task_dumpable(task);
-	} else if (vp) {
-		if (current->pid == pid) {
+
+		if (tgid)
+			*tgid = task->tgid;
+#ifndef VPROC_HOLD_ZERO_GET_TASK
+		put_task_struct(task);
+#endif
+	} else {
+		if (current->pid == vp->vp_pid) {
 			/* process is migrating here, no need to go remote
 			 * since /proc inodes get created...create local
 			 * entry and use current's values, since they
 			 * have just been copied in.
 			 */
-			euid = current->euid;
-			egid = current->egid;
+			task = current;
+			euid = task->euid;
+			egid = task->egid;
 			dumpable = 1;
-			pid_alive = 1;
+			if (tgid)
+				*tgid = task->tgid;
 		} else {
 			/*
 			 * Task on remote node. Get the attributes from remote 
 			 * node
 			 */
-			error = PVPOP_PROCFS_GETATTR(vp, 0, 0, &dumpable, &euid, &egid, 0);
-			if (error) {
-				VPROC_RELE(vp, "temp proc_pid_make_inode");
+			if (PVPOP_PROCFS_GETATTR(vp, 0, 0, &dumpable, &euid, &egid, tgid))
 				goto out_unlock;
-			}
 		}
 	}
 
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-	inode->i_ino = fake_ino(pid, ino);
-
-#ifdef VPROC_IS_ALIVE
-	if (!pid_alive && !vproc_is_alive(vp)) {
-#else
-	if (!pid_alive && !process_is_alive(pid)) {
-#endif
-		VPROC_RELE(vp, "temp proc_pid_make_inode");
-		goto out_unlock;
-	}
+	inode->i_ino = fake_ino(vp->vp_pid, ino);
 
+	/*
+	 * grab the reference to vproc.
+	 */
+	VPROC_HOLD(vp, "proc_pid_make_inode");
 	ei->vproc = vp;
 	ei->type = ino;
 	inode->i_uid = 0;
@@ -1475,6 +1505,10 @@
 		inode->i_uid = euid;
 		inode->i_gid = egid;
 	}
+#if 0
+	if (task)
+		security_task_to_inode(task, inode);
+#endif
 #else
 	ei->task = NULL;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
@@ -1544,7 +1578,6 @@
 		/* security_task_to_inode(task, inode); */
 		return 1;
 	}
-
 #else
 	struct inode *inode = dentry->d_inode;
 	struct task_struct *task = proc_task(inode);
@@ -1638,7 +1671,7 @@
 #ifdef CONFIG_SSI
 	/* For remote processes return 1, so dentry is not in cache */
 #ifdef VPROC_HOLD_ZERO_GET_TASK
-	return !(PVP(proc_vproc(dentry->d_inode))->pvp_flag & PV_IS_LOCAL);
+	return !PV_IS_ALIVE(PVP(proc_vproc(dentry->d_inode)));
 #else
 	return !proc_task((dentry->d_inode));
 #endif
@@ -1693,12 +1726,12 @@
 /* SMP-safe */
 static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
 {
-	struct task_struct *task = proc_task(dir);
 	unsigned fd = name_to_int(dentry);
 #ifdef CONFIG_SSI
 	int ret;
 	mode_t f_mode;
 #else
+	struct task_struct *task = proc_task(dir);
 	struct file * file;
 	struct files_struct * files;
 #endif
@@ -1708,22 +1741,11 @@
 	if (fd == ~0U)
 		goto out;
 #ifdef CONFIG_SSI
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	task = proc_ssi_task(proc_vproc(dir));
-#endif
-#ifdef VPROC_IS_ALIVE
-	if (!vproc_is_alive(proc_vproc(dir)))
-		goto out;
-#else
-	if (!process_is_alive(proc_vproc(dir)->vp_pid))
-		goto out;
-#endif
-	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd,
-						proc_vproc(dir)->vp_pid);
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	if (task)
-		put_task_struct(task);
-#endif
+	/* SSI: we let proc_pid_make_inode() perform the pid_alive() check */
+	VPROC_HOLD_MOVEMENT(proc_vproc(dir), "proc_pident_lookup");
+
+	inode = proc_pid_make_inode(dir->i_sb, proc_vproc(dir), PROC_TID_FD_DIR+fd, NULL);
+	VPROC_RELEASE_MOVEMENT(proc_vproc(dir), "proc_pident_lookup");
 #else
 	if (!pid_alive(task))
 		goto out;
@@ -1772,8 +1794,8 @@
 	spin_unlock(&files->file_lock);
 	put_files_struct(files);
 out_unlock:
-#endif
 	iput(inode);
+#endif
 out:
 	return ERR_PTR(-ENOENT);
 }
@@ -1894,13 +1916,18 @@
 {
 	struct inode *inode;
 	int error;
+#ifndef CONFIG_SSI
 	struct task_struct *task = proc_task(dir);
+#endif
 	struct pid_entry *p;
 	struct proc_inode *ei;
 
 	error = -ENOENT;
 	inode = NULL;
+
 #ifdef CONFIG_SSI
+	/* SSI: we let proc_pid_make_inode() perform the pid_alive() check */
+#if 0
 #ifdef VPROC_IS_ALIVE
 	if (proc_vproc(dir)->vp_pid != current->pid &&
 	    !vproc_is_alive(proc_vproc(dir)))
@@ -1910,6 +1937,7 @@
 	    !process_is_alive(proc_vproc(dir)->vp_pid))
 		goto out;
 #endif
+#endif
 #else
 	if (!pid_alive(task))
 		goto out;
@@ -1926,14 +1954,11 @@
 
 	error = -EINVAL;
 #ifdef CONFIG_SSI
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	task = proc_ssi_task(proc_vproc(dir));
-#endif
-	inode = proc_pid_make_inode(dir->i_sb, task, p->type, proc_vproc(dir)->vp_pid);
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	if (task)
-		put_task_struct(task);
-#endif
+	VPROC_HOLD_MOVEMENT(proc_vproc(dir), "proc_pident_lookup");
+
+	inode = proc_pid_make_inode(dir->i_sb, proc_vproc(dir), p->type, NULL);
+
+	VPROC_RELEASE_MOVEMENT(proc_vproc(dir), "proc_pident_lookup");
 #else
 	inode = proc_pid_make_inode(dir->i_sb, task, p->type);
 #endif
@@ -2262,13 +2287,14 @@
 /* SMP-safe */
 struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
-	struct task_struct *task = NULL;
+	struct task_struct *task;
 	struct inode *inode;
 	struct proc_inode *ei;
 	unsigned tgid;
 	int died;
 #ifdef CONFIG_SSI
-	struct vproc *vp = NULL;
+	struct vproc *vp;
+	int hold_movement = 1;
 #endif
 
 	if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
@@ -2295,28 +2321,27 @@
 	if (!vp)
 		goto out;
 
+	/*
+	 * If pid is migrating in then skip unhash, avoid deadlocking
+	 * the pvpop since it needs to grab the movement lock
+	 */
+	if (current->ppid == 2 && current->p_vproc->vp_pid != vp->vp_pid &&
+			current->pid == vp->vp_pid) {
+		hold_movement = 0;
+	} else
+		VPROC_HOLD_MOVEMENT(vp, "proc_pid_lookup");
+
 #ifdef VPROC_HOLD_ZERO_GET_TASK
 	if (PVP(vp)->pvp_flag & PV_IS_LOCAL) {
 		task = PVP(vp)->pvp_pproc;
 		get_task_struct(task);
-	}
-#else
-#ifdef VPROC_RW_LOCK
-	VPROC_LOCK_SHARED(vp, "proc_pid_lookup");
-#else
-	VPROC_LOCK_EXCL(vp, "proc_pid_lookup");
-#endif
-	task = PVP(vp)->pvp_pproc;
-	if (task)
-		get_task_struct(task);
-#ifdef VPROC_RW_LOCK
-	VPROC_UNLOCK_SHARED(vp, "proc_pid_lookup");
+	} else { /* remote process */
+		task = NULL;
 #else
-	VPROC_UNLOCK_EXCL(vp, "proc_pid_lookup");
-#endif
+	task = proc_ssi_task(vp);
+	if( task == NULL ) { /* remote process */
 #endif /* !VPROC_HOLD_ZERO_GET_TASK */
 
-	if( task == NULL ) { /* remote process */
 		 if (PVP(current->p_vproc)->pvp_localview == 1 || 
 				 ( !PIDNODE(tgid) && (tgid != 1) )) {
 			 /* 
@@ -2327,21 +2352,21 @@
 			  * It should have a task_struct.Otherwise it is
 			  * a non existent tgid
 			  */
+			if (hold_movement)
+				VPROC_RELEASE_MOVEMENT(vp, "proc_pid_lookup");
 			VPROC_RELE(vp, "proc_pid_lookup");
 			goto out;
 		 }
 	}
 
-	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO, tgid);
-
-	/*
-	 * proc_pid_make_inode decrement the vproc reference count 
-	 */
-	VPROC_RELE(vp, "proc_pid_lookup");
+	inode = proc_pid_make_inode(dir->i_sb, vp, PROC_TGID_INO, NULL);
 
 	if (!inode ) {
 		if (task)
 			put_task_struct(task);
+		if (hold_movement)
+			VPROC_RELEASE_MOVEMENT(vp, "proc_pid_lookup");
+		VPROC_RELE(vp, "proc_pid_lookup");
 		goto out;
 
 	}
@@ -2355,6 +2380,8 @@
 		goto out;
 
 	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
+
+
 	if (!inode) {
 		put_task_struct(task);
 		goto out;
@@ -2370,55 +2397,46 @@
 
 	died = 0;
 	d_add(dentry, inode);
+#ifdef CONFIG_SSI
 	if(task) {
 		/*
 		 * SSI_XXX this takes care of only local task. 
 		 * For remote pid lookups the dentry that gets hashed will
 		 * get unhashed when pid_revalidate() gets called
 		 */
-		spin_lock(&task->proc_lock);
-		task->proc_dentry = dentry;
-		if (!pid_alive(task)) {
-			dentry = proc_pid_unhash(task);
-			died = 1;
-		}
-		spin_unlock(&task->proc_lock);
-
-		put_task_struct(task);
+#endif
+	spin_lock(&task->proc_lock);
+	task->proc_dentry = dentry;
+	if (!pid_alive(task)) {
+		dentry = proc_pid_unhash(task);
+		died = 1;
 	}
+	spin_unlock(&task->proc_lock);
+
+	put_task_struct(task);
 #ifdef CONFIG_SSI
+	}
+#if 0
 #ifdef VPROC_IS_ALIVE
-	else {
-		vp = proc_vproc(inode);
-
-		/*
-		 * If pid is migrating in then skip unhash, avoid deadlocking
-		 * the pvpop since it needs to grab the movement lock
-		 */
-		if (current->ppid == 2 && current->p_vproc->vp_pid != vp->vp_pid &&
-				current->pid == vp->vp_pid)
-			return NULL;
-
-		if (!vproc_is_alive(vp)) {
-			struct dentry *proc_dentry = dentry;
-
-			/* Remote pid is dead */
-			/* Shameless dupe of proc_pid_unhash() */
-			if (proc_dentry != NULL) {
-
-				spin_lock(&dcache_lock);
-				if (!d_unhashed(proc_dentry)) {
-					dget_locked(proc_dentry);
-					__d_drop(proc_dentry);
-				} else
-					proc_dentry = NULL;
-				spin_unlock(&dcache_lock);
-			}
-			died = 1;
+	else if (hold_movement && !vproc_is_alive(vp)) {
+		/* Shameless dupe of proc_pid_unhash() */
+		if (dentry != NULL) {
+			spin_lock(&dcache_lock);
+			if (!d_unhashed(dentry)) {
+				dget_locked(dentry);
+				__d_drop(dentry);
+			} else
+				dentry = NULL;
+			spin_unlock(&dcache_lock);
 		}
+		died = 1;
 	}
 #endif
 #endif
+	if (hold_movement)
+		VPROC_RELEASE_MOVEMENT(vp, "proc_pid_lookup");
+	VPROC_RELE(vp, "proc_pid_lookup");
+#endif /* CONFIG_SSI */
 	if (died) {
 		proc_pid_flush(dentry);
 		goto out;
@@ -2431,16 +2449,15 @@
 /* SMP-safe */
 static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
-	struct task_struct *task = NULL;
+	struct task_struct *task;
 #ifndef CONFIG_SSI
 	struct task_struct *leader = proc_task(dir);
 #endif
 	struct inode *inode;
 	unsigned tid;
 #ifdef CONFIG_SSI
-	struct vproc *vp = NULL;
-	struct vproc *leader = proc_vproc(dir);
-	int tgid, error;
+	struct vproc *vp, *leader = proc_vproc(dir);
+	int tgid;
 #endif
 
 	tid = name_to_int(dentry);
@@ -2452,49 +2469,23 @@
 	if (!vp)
 		goto out;
 
+	VPROC_HOLD_MOVEMENT(vp, "proc_task_lookup");
 #ifdef VPROC_HOLD_ZERO_GET_TASK
 	if (PVP(vp)->pvp_flag & PV_IS_LOCAL) {
 		task = PVP(vp)->pvp_pproc;
+		/* leader's pid should be this vproc tgid */
+		if (leader->vp_pid != task->tgid) {
+			VPROC_RELEASE_MOVEMENT(vp, "proc_task_lookup");
+			VPROC_RELE(vp, "proc_task_lookup");
+			goto out;
+		}
 		get_task_struct(task);
-	}
-#else
-#ifdef VPROC_RW_LOCK
-	VPROC_LOCK_SHARED(vp, "proc_task_lookup");
-#else
-	VPROC_LOCK_EXCL(vp, "proc_task_lookup");
-#endif
-	task = PVP(vp)->pvp_pproc;
-	if (task)
-		get_task_struct(task);
-#ifdef VPROC_RW_LOCK
-	VPROC_UNLOCK_SHARED(vp, "proc_task_lookup");
+	} else { /* remote process */
+		task = NULL;
 #else
-	VPROC_UNLOCK_EXCL(vp, "proc_task_lookup");
-#endif
-#endif /* !VPROC_HOLD_ZERO_GET_TASK */
-
-	/*
-	 * SSI_XXX tgid fetching is not yet implemented. 
-	 * We can also move the GETATTR to proc_pid_make_inode
-	 */
-	error = PVPOP_PROCFS_GETATTR(vp, 0, 0, NULL, NULL, NULL, &tgid);
-
-	/* leader's pid should be this vproc tgid */
-	if ( error || leader->vp_pid != tgid ) {
-		VPROC_RELE(vp, "proc_task_lookup");
-#ifdef PROC_TASK_LOOKUP_FIX
-		/* [ ssic-linux-Bugs-1938520 ]
-		 * Any attempt to do stat ("/proc/pid1/task/pid2") where pid2
-		 * is not pid1 and pid2 is not on the node doing the stat
-		 * causes the oops.	-hughesj
-		 */
-		if (!task)
-			goto out;
-#endif
-		goto out_drop_task;
-	}
-
+	task = proc_ssi_task(vp);
 	if( task == NULL ) { /* remote process */
+#endif /* !VPROC_HOLD_ZERO_GET_TASK */
 		 if (PVP(current->p_vproc)->pvp_localview == 1 ||
 				 ( !PIDNODE(tid) && (tid != 1) )) {
 			 /* 
@@ -2505,23 +2496,31 @@
 			  * It should have a task_struct.Otherwise it is
 			  * a non existent tid
 			  */
+			VPROC_RELEASE_MOVEMENT(vp, "proc_task_lookup");
 			VPROC_RELE(vp, "proc_task_lookup");
 			goto out;
 		 }
 	}
 
-	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO, tid);
-	/*
-	 * proc_pid_make_inode increment the vproc reference count 
-	 */
+	inode = proc_pid_make_inode(dir->i_sb, vp, PROC_TID_INO, &tgid);
+
+	VPROC_RELEASE_MOVEMENT(vp, "proc_task_lookup");
 	VPROC_RELE(vp, "proc_task_lookup");
 
-	if (!inode ) {
-		if (task)
-			goto out_drop_task;
-		else 
+	/* leader's pid should be this vproc tgid */
+	if (!inode || (!task && leader->vp_pid != tgid)) {
+#ifdef PROC_TASK_LOOKUP_FIX
+		/* [ ssic-linux-Bugs-1938520 ]
+		 * Any attempt to do stat ("/proc/pid1/task/pid2") where pid2
+		 * is not pid1 and pid2 is not on the node doing the stat
+		 * causes the oops.	-hughesj
+		 */
+		if (!task) {
+			iput(inode);
 			goto out;
-
+		}
+#endif
+		goto out_drop_task;
 	}
 #else
 
@@ -2538,6 +2537,7 @@
 
 	inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
 
+
 	if (!inode)
 		goto out_drop_task;
 #endif
@@ -2551,8 +2551,10 @@
 
 	d_add(dentry, inode);
 
+#ifdef CONFIG_SSI
 	if( task )
-		put_task_struct(task);
+#endif
+	put_task_struct(task);
 	return NULL;
 out_drop_task:
 	put_task_struct(task);
@@ -2637,7 +2639,13 @@
 /* for the /proc/ directory itself, after non-process stuff has been done */
 int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
+#ifdef PROC_LARGE_MAXPIDS
+	unsigned int __tgid_array[PROC_MAXPIDS];
+	unsigned int *tgid_array;
+	int localview = PVP(current->p_vproc)->pvp_localview;
+#else
 	unsigned int tgid_array[PROC_MAXPIDS];
+#endif
 	char buf[PROC_NUMBUF];
 	unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
 	unsigned int nr_tgids, i;
@@ -2656,12 +2664,25 @@
 	 */
 	next_tgid = filp->f_version;
 	filp->f_version = 0;
+#ifdef PROC_LARGE_MAXPIDS
+	if (!localview) {
+		tgid_array = kmalloc(VPROC_MAXPIDS *
+					sizeof(unsigned int), GFP_KERNEL);
+		if (!tgid_array)
+			return -ENOMEM;
+	} else
+		tgid_array = __tgid_array;
+#endif
 	for (;;) {
 #ifdef CONFIG_SSI
 		/* SSI_XXX: ssi_get_tgid_list() wasn't necessarily designed 
 		 * 	    to be called in a loop like this
 		 */
+#ifdef PROC_LARGE_MAXPIDS
+		if (!localview) {
+#else
 		if ( !PVP(current->p_vproc)->pvp_localview ) {
+#endif
 			/*
 			 * Clusterwide listing 
 			 */
@@ -2676,6 +2697,9 @@
 		}
 		next_tgid = 0;
 
+#ifdef PROC_LARGE_MAXPIDS
+		if (localview)
+#endif
 		/* do not use the last found pid, reserve it for next_tgid */
 		if (nr_tgids == PROC_MAXPIDS) {
 			nr_tgids--;
@@ -2702,6 +2726,10 @@
 		}
 	}
 out:
+#ifdef PROC_LARGE_MAXPIDS
+	if (!localview)
+		kfree(tgid_array);
+#endif
 	return 0;
 }
 
@@ -2718,11 +2746,14 @@
 	unsigned long pos = filp->f_pos;  /* avoiding "long long" filp->f_pos */
 
 #ifdef CONFIG_SSI
+	struct vproc *vp = proc_vproc(inode);
 #ifndef VPROC_HOLD_ZERO_GET_TASK
 	task_t *task = NULL;
 #endif
 	u_int *tids;
 
+	/* SSI: we skip possible remote pid_alive() check here */
+#if 0
 #ifdef VPROC_IS_ALIVE
 	if (!vproc_is_alive(proc_vproc(inode)))
 		goto out;
@@ -2730,6 +2761,7 @@
 	if (!process_is_alive(proc_vproc(inode)->vp_pid))
 		goto out;
 #endif
+#endif
 #else
 	if (!pid_alive(proc_task(inode)))
 		goto out;
@@ -2750,31 +2782,32 @@
 		pos++;
 		/* fall through */
 	}
+
 #ifdef CONFIG_SSI
+	VPROC_HOLD_MOVEMENT(vp, "proc_task_readdir");
 #ifndef VPROC_HOLD_ZERO_GET_TASK
-	task = proc_ssi_task(proc_vproc(inode));
+	task = proc_ssi_task(vp);
 	if ( !PVP(current->p_vproc)->pvp_localview || !task) {
 #else
 	if (!PVP(current->p_vproc)->pvp_localview ||
-	    !(PVP(proc_vproc(inode))->pvp_flag & PV_IS_LOCAL)) {
+	    !(PVP(vp)->pvp_flag & PV_IS_LOCAL)) {
 #endif
-		struct vproc *vp = proc_vproc(inode);
 		int len;
 		/*
 		 * remote listing
 		 */
-		VPROC_HOLD(vp, "proc_task_readdir");
+		/* VPROC_HOLD(vp, "proc_task_readdir"); */
 		len = PROC_MAXPIDS;
 		tids = tid_array;
 		nr_tids = PVPOP_PROCFS_TID_LIST(vp, pos, &tids, &len);
-		VPROC_RELE(vp, "proc_task_readdir");
-	}
-	else {
+		/* VPROC_RELE(vp, "proc_task_readdir"); */
+	} else {
 		nr_tids = get_tid_list(pos, tid_array, inode);
 #ifndef VPROC_HOLD_ZERO_GET_TASK
 		put_task_struct(task);
 #endif
 	}
+	VPROC_RELEASE_MOVEMENT(vp, "proc_task_readdir");
 #else
 	nr_tids = get_tid_list(pos, tid_array, inode);
 #endif
@@ -2804,7 +2837,7 @@
 	struct inode *inode = NULL;
 	int error = -ENOMEM;
 
-	inode = proc_pid_make_inode(proc_super, p, 0, (p->p_vproc)->vp_pid);
+	inode = proc_pid_make_inode(proc_super, p->p_vproc, 0, NULL);
 	if (!inode)
 		return error;
 
@@ -3086,28 +3119,23 @@
 	struct inode *inode;
 	struct dentry *de;
 	struct vfsmount *mnt = NULL;
-	int error = ENOMEM;
+	int error;
 
-	inode = proc_pid_make_inode(proc_super, PVP(vp)->pvp_pproc, type,
-				    vp->vp_pid);
-	if (!inode) {
-#ifdef VPROC_RW_LOCK
-		VPROC_UNLOCK_SHARED(vp, "pvpop_proc_readlink");
-#else
-		VPROC_UNLOCK_EXCL(vp, "pvpop_proc_readlink");
-#endif
-		return error;
-	}
+	inode = proc_pid_make_inode(proc_super, vp, type, NULL);
+	if (!inode)
+		return -ENOMEM;
 
 	error = proc_check_root(inode);
-	if (error) {
-#ifdef VPROC_RW_LOCK
-		VPROC_UNLOCK_SHARED(vp, "pvpop_proc_readlink");
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	if (error)
+		goto out_nolock;
+
+	if (buffer)
+		lock_kernel(); /* for proc_pid_readlink() */
 #else
-		VPROC_UNLOCK_EXCL(vp, "pvpop_proc_readlink");
-#endif
+	if (error)
 		goto out;
-	}
+#endif
 
 	switch(type) {
 		case PROC_TGID_EXE:
@@ -3126,12 +3154,16 @@
 			error = proc_fd_link(inode, &de, &mnt);
 			break;
 	}
+#ifdef SSI_NOTUSED
+/* SSI_XXX: SSI-1.9.6 proc_pid_make_inode() may acquire VPROC lock. */
 #ifdef VPROC_RW_LOCK
 	VPROC_UNLOCK_SHARED(vp, "pvpop_proc_readlink");
 #else
 	VPROC_UNLOCK_EXCL(vp, "pvpop_proc_readlink");
 #endif
-	if (error < 0)
+#endif
+	//if (error < 0)
+	if (error)
 		goto out;
 
 	/* For the proc_pid_readlink() case, fill in the buffer and
@@ -3139,7 +3171,11 @@
 	 * has a NULL buffer ptr since it doesnt need to send anything
 	 * back to user.
 	 */
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	if (buffer) {
+#else
 	if (buffer && (buflen != 0)) {
+#endif
 		error = do_proc_readlink(de, mnt, buffer, buflen);
 		dput(de);
 		mntput(mnt);
@@ -3156,6 +3192,11 @@
 		*vfsmnt = mnt;
 	}
 out:
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	if (buffer)
+		unlock_kernel();
+out_nolock:
+#endif
 	iput(inode);
 	return error;
 }

Index: proc_cluster.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/proc_cluster.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- proc_cluster.c	19 Feb 2009 08:01:02 -0000	1.14
+++ proc_cluster.c	24 Mar 2009 04:26:29 -0000	1.15
@@ -38,18 +38,30 @@
 /* 4K page size but our output routines use some slack for overruns */
 #define PROC_BLOCK_SIZE (3*1024)
 
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
+#define PROC_CLUSTER_NODELIST_START \
+	/* Get nodes that are UP */ \
+	nodelist = clms_get_nsc_nodelist(CLMS_NODE_UP); \
+	NSC_NLCOOKIE_INIT(&cookie); \
+	NSC_NODELIST_CLR1(nodelist, this_node); \
+	node = NSC_NODELIST_GET_NEXT(&cookie,nodelist); \
+	while (node != CLUSTERNODE_INVAL) { \
+		sprintf(nodename, "node%u", node); \
+		for (ptr = de->subdir; ptr ; ptr = ptr->next) { \
+			if (proc_match(strlen(nodename), nodename, ptr)) \
+				break; \
+		}
 
-#ifdef CONFIG_LDLVL
+#define PROC_CLUSTER_NODELIST_END \
+		node = NSC_NODELIST_GET_NEXT(&cookie,nodelist); \
+	}
 
+#ifdef CONFIG_LDLVL
 static int
 proc_node_read_load(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
 	int len;
-	clusternode_t node;
-
-	node = (clusternode_t)data;
+	clusternode_t node = (clusternode_t)data;
 
 	len = sprintf(page,"%lu\n",
 #ifdef CONFIG_MOSIX_LL
@@ -59,32 +71,44 @@
 #endif
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
-
 #endif
 
 static int
 proc_cluster_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-	struct proc_dir_entry * de;
-	unsigned int ino;
-	int i;
+	struct proc_dir_entry *de, *ptr;
 	struct inode *inode = filp->f_dentry->d_inode;
 	nsc_nodelist_t *nodelist;
 	nsc_nlcookie_t cookie;
 	clusternode_t node;
 	char nodename[16];
-	int index;
-	struct proc_dir_entry *ptr;
+	unsigned int ino;
+	int i, index;
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	int ret = 0;
 
+	lock_kernel(); /* see proc_cluster_lookup() */
+#endif
 	ino = inode->i_ino;
 	de = PDE(inode);
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	if (!de) {
+		ret = -EINVAL;
+		goto out;
+	}
+#else
 	if (!de)
 		return -EINVAL;
+#endif
 	i = filp->f_pos;
 	switch (i) {
 		case 0:
 			if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+				goto out;
+#else
 				return 0;
+#endif
 			i++;
 			filp->f_pos++;
 			/* fall through */
@@ -92,39 +116,54 @@
 			if (filldir(dirent, "..", 2, i,
 				    parent_ino(filp->f_dentry),
 				    DT_DIR) < 0)
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+				goto out;
+#else
 				return 0;
+#endif
 			i++;
 			filp->f_pos++;
 			/* fall through */
 		case 2 :
-			/* Get nodes that are UP */
-			nodelist = clms_get_nsc_nodelist(CLMS_NODE_UP);
-			NSC_NLCOOKIE_INIT(&cookie);
-			NSC_NODELIST_CLR1(nodelist, this_node);
-			node = NSC_NODELIST_GET_NEXT(&cookie,nodelist);
 			index = i;
-			while (node != CLUSTERNODE_INVAL) {
-				sprintf(nodename, "node%u", node);
-				for (ptr = de->subdir; ptr ; ptr = ptr->next) {
-					if (!memcmp(nodename, ptr->name,
-					MAX(ptr->namelen, strlen(nodename))))
-						break;
-				}
-				if (ptr == NULL) {
-					if (filldir(dirent, nodename,
-							strlen(nodename),
-							index++, ino,
-							DT_DIR) < 0)
-						return 0;
-					filp->f_pos++;
-				}
-				node = NSC_NODELIST_GET_NEXT(&cookie,nodelist);
+			PROC_CLUSTER_NODELIST_START;
+			if (ptr == NULL) {
+				if (filldir(dirent, nodename,
+						strlen(nodename),
+						index++, ino,
+						DT_DIR) < 0)
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+					goto out;
+#else
+					return 0;
+#endif
+				filp->f_pos++;
 			}
+			PROC_CLUSTER_NODELIST_END;
 			/* fall through */
-
 		default:
 			de = de->subdir;
 			i -= 2;
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+			for (;;) {
+				if (!de) {
+					ret = 1;
+					goto out;
+				}
+				if (!i)
+					break;
+				de = de->next;
+				i--;
+			}
+
+			do {
+				if (filldir(dirent, de->name, de->namelen, filp->f_pos,
+					    de->low_ino, de->mode >> 12) < 0)
+					goto out;
+				filp->f_pos++;
+				de = de->next;
+			} while (de);
+#else
 			for (;;) {
 				if (!de)
 					return 1;
@@ -141,8 +180,15 @@
 				filp->f_pos++;
 				de = de->next;
 			} while (de);
+#endif
 	}
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	ret = 1;
+out:	unlock_kernel();
+	return ret;
+#else
 	return 1;
+#endif
 }
 
 static struct file_operations proc_cluster_operations = {
@@ -211,7 +257,9 @@
 {
 	unsigned long page;
 	unsigned long action;
+#ifndef PROC_CLUSTER_DIR_ENTRY_FIX
 	char nodename[16];
+#endif
 	clusternode_t node;
 	int error = 0;
 
@@ -231,11 +279,15 @@
 		goto out;
 	}
 
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	node = (clusternode_t) PDE(file->f_dentry->d_inode)->data;
+#else
 	/* Use the file struct to get the back pathwalk and
 	 * see which node its wants.
 	 */
 	 sprintf(nodename, "%s", file->f_dentry->d_parent->d_name.name);
 	 node = simple_strtoul((char *)nodename+4, NULL, 10);
+#endif
 
 	 if (node) {
 		error = PVPSOP_LOADLEVEL_WRITE(node, action);
@@ -253,16 +305,61 @@
 };
 #endif
 
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+#ifdef SSI_NOTYET
+static int proc_cluster_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+	clusternode_t node = (clusternode_t) PDE(dentry->d_inode)->data;
+
+	if (node && node != this_node && !clms_isnodeup(node)) {
+		struct proc_dir_entry *de;
+		char nodename[16];
+
+		sprintf(nodename, "node%u", node);
+		lock_kernel();
+#ifdef CONFIG_LDLVL
+		for (de = proc_cluster->subdir; de ; de = de->next) {
+			if (node == (clusternode_t)de->data) {
+				remove_proc_entry("loadlevel", de);
+				remove_proc_entry("load", de);
+				break;
+			}
+		}
+#endif
+		remove_proc_entry(nodename, proc_cluster);
+		unlock_kernel();
+		return 0;
+	}
+	return 1;
+}
+
+static struct dentry_operations proc_cluster_dentry_operations =
+{
+	.d_revalidate = proc_cluster_revalidate,
+	/* .d_delete = proc_cluster_delete_dentry, */
+};
+#endif /* SSI_NOTYET */
+#endif /* PROC_CLUSTER_DIR_ENTRY_FIX */
+
 static void
 proc_cluster_node_init(void)
 {
-	struct proc_dir_entry *proc_cluster_node;
-	struct proc_dir_entry *node_loadlevel_entry;
+	struct proc_dir_entry *proc_cluster_node, *node_loadlevel_entry;
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	char nodedir[16];
+
+	lock_kernel();
+
+	/* Setup node specific entries */
+	sprintf(nodedir, "node%u", this_node);
+	proc_cluster_node = proc_mkdir(nodedir, proc_cluster);
+#else
 	char nodedir[32];
 
 	/* Setup node specific entries */
 	sprintf(nodedir, "cluster/node%u", this_node);
 	proc_cluster_node = proc_mkdir(nodedir, 0);
+#endif
 	proc_cluster_node->data = (void *)this_node;
 
 #ifdef CONFIG_LDLVL
@@ -283,79 +380,102 @@
 #else
 	(void)node_loadlevel_entry;
 #endif
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	unlock_kernel();
+#endif
 }
 
 static struct dentry *
 proc_cluster_lookup(struct inode * dir, struct dentry *dentry,
 		    struct nameidata *nd)
 {
-	struct inode *inode;
-	struct proc_dir_entry * de;
-	int error;
+	struct proc_dir_entry *de, *nodedir, *node_entry, *ptr;
+	struct inode *inode = NULL;
+	int error = -ENOENT;
 	nsc_nodelist_t *nodelist;
 	nsc_nlcookie_t cookie;
 	clusternode_t node;
 	char nodename[16];
-	struct proc_dir_entry *nodedir;
-	struct proc_dir_entry *node_entry;
-	struct proc_dir_entry *ptr;
 
-	error = -ENOENT;
-	inode = NULL;
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	lock_kernel();
+#endif
 	de = PDE(dir);
 	if (de) {
-		nodelist = clms_get_nsc_nodelist(CLMS_NODE_UP);
-		NSC_NLCOOKIE_INIT(&cookie);
-		NSC_NODELIST_CLR1(nodelist, this_node);
-		node = NSC_NODELIST_GET_NEXT(&cookie,nodelist);
-		while (node != CLUSTERNODE_INVAL) {
-			sprintf(nodename, "node%u", node);
-			for (ptr = de->subdir; ptr ; ptr = ptr->next) {
-				if (!memcmp(nodename, ptr->name,
-					MAX(strlen(nodename), ptr->namelen)))
-					break;
+		PROC_CLUSTER_NODELIST_START;
+		if (ptr == NULL) {
+			nodedir = proc_mkdir(nodename, proc_cluster);
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+			if (!nodedir) {
+				printk(KERN_WARNING "%s: Unable to "
+					"create cluster/%s\n",
+					__FUNCTION__, nodename);
+				goto next_node;
 			}
-			if (ptr == NULL) {
-				nodedir = proc_mkdir(nodename, proc_cluster);
-				nodedir->data = (void *)node;
+#endif
+			nodedir->data = (void *)node;
 #ifdef CONFIG_LDLVL
-				create_proc_read_entry("load",
-						S_IFREG|S_IRUSR|S_IRGRP|S_IROTH,
-						nodedir,
-						proc_node_read_load,
-						(void *)node);
+			create_proc_read_entry("load",
+					S_IFREG|S_IRUSR|S_IRGRP|S_IROTH,
+					nodedir,
+					proc_node_read_load,
+					(void *)node);
 
-				node_entry = create_proc_entry("loadlevel",
-					S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
-						nodedir);
-				if (node_entry) {
-					node_entry->proc_fops = &proc_loadlevel_operations;
-					node_entry->data = (void *)node;
-				}
+			node_entry = create_proc_entry("loadlevel",
+				S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
+					nodedir);
+			if (node_entry) {
+				node_entry->proc_fops = &proc_loadlevel_operations;
+				node_entry->data = (void *)node;
+			}
 #else
-				(void)node_entry;
+			(void)node_entry;
 #endif
-			}
-			node = NSC_NODELIST_GET_NEXT(&cookie,nodelist);
 		}
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+next_node:
+#endif
+		PROC_CLUSTER_NODELIST_END;
+
 		for (de = de->subdir; de ; de = de->next) {
-			if (!de || !de->low_ino)
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+			if (proc_match(dentry->d_name.len,
+					dentry->d_name.name, de)) {
+				int ino = de->low_ino;
+
+				node = (clusternode_t) de->data;
+				if (node && node != this_node &&
+				    !clms_isnodeup(node))
+					break;
+#else
+			if (!de || !de->low_ino) /* wtf? */
 				continue;
 			if (de->namelen != dentry->d_name.len)
 				continue;
 			if (!memcmp(dentry->d_name.name, de->name,
-					MAX(de->namelen, dentry->d_name.len))) {
+					dentry->d_name.len)) {
 				int ino = de->low_ino;
+#endif
 				error = -EINVAL;
 				inode = proc_get_inode(dir->i_sb, ino, de);
 				break;
 			}
 		}
 	}
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+	unlock_kernel();
+#endif
 
 	if (inode) {
+#ifdef PROC_CLUSTER_DIR_ENTRY_FIX
+#ifdef SSI_NOTYET
+		dentry->d_op = &proc_cluster_dentry_operations;
+#endif
+		return d_add_unique(dentry, inode);
+#else
 		d_add(dentry, inode);
 		return NULL;
+#endif
 	}
 	return ERR_PTR(error);
 }
@@ -442,14 +562,20 @@
 	if (!devp)
 		return path;
 	devp += 4;
+
 	node = itocmi(inode)->mi_server;
+
 	nlen = snprintf(buf, 0, "/dev/%u", node);
 	if (devp - buf < nlen || nlen >= sizeof(save_path))
 		return path;
+
 	path = devp - nlen;
+
 	memcpy(save_path, path, nlen + 1);
+
 	(void)snprintf(path, nlen + 1, "/dev/%u", node);
 	devp[0] = '/';
+
 	error  = path_lookup(path, LOOKUP_FOLLOW, &tnd);
 	if (error < 0 || tnd.dentry->d_inode != inode) {
 		memcpy(path, save_path, nlen + 1);

Index: array.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/array.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- array.c	3 Feb 2009 06:18:13 -0000	1.7
+++ array.c	24 Mar 2009 04:26:29 -0000	1.8
@@ -163,9 +163,6 @@
 	int g;
 
 	read_lock(&tasklist_lock);
-	/* SSI_XXX: the GET_OPPID() below incorrectly replaces
-	 * 	    p->group_leader->real_parent->tgid
-	 */
 	buffer += sprintf(buffer,
 		"State:\t%s\n"
 		"SleepAVG:\t%lu%%\n"
@@ -178,8 +175,16 @@
 		get_task_state(p),
 		(p->sleep_avg/1024)*100/(1020000000/1024),
 	       	p->tgid,
+#ifdef CONFIG_SSI
+		/* SSI_XXX: the GET_OPPID() below incorrectly replaces
+		 * 	    p->group_leader->real_parent->tgid
+		 */
 		p->pid, pid_alive(p) ? GET_OPPID(p) : 0,
 		pid_alive(p) && p->ptrace ? GET_PPID(p) : 0,
+#else
+		p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0,
+		pid_alive(p) && p->ptrace ? p->parent->pid : 0,
+#endif
 		p->uid, p->euid, p->suid, p->fsuid,
 		p->gid, p->egid, p->sgid, p->fsgid);
 	read_unlock(&tasklist_lock);
@@ -337,13 +342,20 @@
 
 	get_task_comm(tcomm, task);
 
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-again:
-#endif
 	sigemptyset(&sigign);
 	sigemptyset(&sigcatch);
 	cutime = cstime = utime = stime = cputime_zero;
 	read_lock(&tasklist_lock);
+#ifdef CONFIG_SSI
+#ifdef VPROC_LOCKING_CONTEXT_FIX
+	if (task->signal &&
+	    ssi_tty_get_pgrp(task, &tty_pgrp) >= 0) {
+		/* Re-check. tasklist_lock could have been released */
+		if (task->signal)
+			tty_nr = new_encode_dev(task->signal->cttydev);
+	}
+#endif
+#endif /* !CONFIG_SSI */
 	if (task->sighand) {
 		spin_lock_irq(&task->sighand->siglock);
 		num_threads = atomic_read(&task->signal->count);
@@ -365,21 +377,16 @@
 	}
 	if (task->signal) {
 #ifdef CONFIG_SSI
-		if (ssi_tty_get_pgrp(task, &tty_pgrp) >= 0) {
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-			if (!task->signal) {
-				read_unlock(&tasklist_lock);
-				goto again;
-			}
-#endif
+#ifndef VPROC_LOCKING_CONTEXT_FIX
+		if (ssi_tty_get_pgrp(task, &tty_pgrp) >= 0)
 			tty_nr = new_encode_dev(task->signal->cttydev);
-		}
+#endif
 #else 
 		if (task->signal->tty) {
 			tty_pgrp = task->signal->tty->pgrp;
 			tty_nr = new_encode_dev(tty_devnum(task->signal->tty));
 		}
-#endif
+#endif /* !CONFIG_SSI */
 		pgid = process_group(task);
 		sid = task->signal->session;
 		cmin_flt = task->signal->cmin_flt;
@@ -394,10 +401,14 @@
 			stime = cputime_add(stime, task->signal->stime);
 		}
 	}
+#ifdef CONFIG_SSI
 	/* SSI_XXX: GET_OPPID() incorrectly replaces
 	 * 	    task->group_leader->real_parent->tgid
 	 */
 	ppid = pid_alive(task) ? GET_OPPID(task) : 0;
+#else
+	ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
+#endif
 	read_unlock(&tasklist_lock);
 
 	if (!whole || num_threads<2)

Index: internal.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/internal.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- internal.h	10 Oct 2008 08:10:32 -0000	1.3
+++ internal.h	24 Mar 2009 04:26:29 -0000	1.4
@@ -81,7 +81,7 @@
         struct vproc *vp = proc_vproc(inode);
         return (PVP(vp)->pvp_pproc);
 #else
-        return PROC_I(inode)->task;
+	return PROC_I(inode)->task;
 #endif
 }
 


------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
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.