[SSI] openssi/kernel/fs/proc base.c, 1.26, 1.27 inode.c, 1.12, 1.13 internal.h, 1.4, 1.5 proc_cluster.c, 1.15, 1.16

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-serv16224/kernel/fs/proc

Modified Files:
      Tag: OPENSSI-FC
	base.c inode.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.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- base.c	28 Mar 2009 23:44:16 -0000	1.26
+++ base.c	27 Oct 2009 03:18:30 -0000	1.27
@@ -506,17 +506,32 @@
 
 static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
+#ifdef TASK_HOLD_VPROC
+	struct vproc *vp;
+	int error;
+#endif
 	if (generic_permission(inode, mask, NULL) != 0)
 		return -EACCES;
 #ifdef CONFIG_SSI
+#ifdef TASK_HOLD_VPROC
+	vp = proc_vproc(inode);
+	error = VPROC_HOLD_MOVEMENT_LOCAL(vp, "proc_permission");
+	if (error == -EREMOTE)
+		return 0;
+
+	error = proc_check_root(inode);
+	VPROC_RELEASE_MOVEMENT(vp, "proc_permission");
+	return error;
+#else
 	/* 
 	 * FIXME!! SSI_XXX Why do we skip the below proc_check_root ? 
 	 */
 	/* NULL proc_task(inode) when remote */
 	return 0;
+#endif
 #else
 	return proc_check_root(inode);
-#endif
+#endif /* !CONFIG_SSI */
 }
 
 extern struct seq_operations proc_pid_maps_op;
@@ -636,12 +651,23 @@
 
 	if (task) {
 #else
+#ifdef TASK_HOLD_VPROC
+	struct vproc *vp = proc_vproc(inode);
+
+	error = VPROC_HOLD_MOVEMENT_LOCAL(vp, "ssi_mounts_open");
+	if (error != -EREMOTE) {
+#else
 	if (PVP(proc_vproc(inode))->pvp_flag & PV_IS_LOCAL) {
 #endif
+#endif
 		int ret;
 		ret = mounts_open(inode, file);
 #ifndef VPROC_HOLD_ZERO_GET_TASK
 		put_task_struct(task);
+#else
+#ifdef TASK_HOLD_VPROC
+		VPROC_RELEASE_MOVEMENT(vp, "ssi_mounts_open");
+#endif
 #endif
 		return ret;
 	}
@@ -654,8 +680,9 @@
 	error = path_lookup("/proc/self/mounts", LOOKUP_FOLLOW, &nd);
 	if (!error) {
 		if (nd.dentry->d_inode) {
-			dput(file->f_dentry);
+			struct dentry *dentry = file->f_dentry;
 			file->f_dentry = dget(nd.dentry);
+			dput(dentry);
 			error = mounts_open(nd.dentry->d_inode, file);
 		}
 		path_release(&nd);
@@ -873,7 +900,7 @@
 	else
 		return mem_write((struct file *)task, buf, count, pos);
 #else
-	/* SSI_XXX: mem_write() is disabled by default in base */
+	/* mem_write() is disabled by default in base */
 	return -EINVAL;
 #endif
 }
@@ -971,7 +998,21 @@
 				size_t count, loff_t *ppos, int type)
 {
 	struct vproc *vp = proc_vproc(file->f_dentry->d_inode);
+#ifdef TASK_HOLD_VPROC
+	int ret;
+
+	ret = VPROC_HOLD_MOVEMENT_LOCAL(vp, "ssi_oom_adjust");
+	if (ret == -EREMOTE)
+		return -EREMOTE;
 
+	if (!type)
+		ret = oom_adjust_read((struct file *) PVP(vp)->pvp_pproc, buf, count, ppos);
+	else
+		ret = oom_adjust_write((struct file *) PVP(vp)->pvp_pproc, buf, count, ppos);
+
+	VPROC_RELEASE_MOVEMENT(vp, "ssi_oom_adjust");
+	return ret;
+#else
 	if (PVP(vp)->pvp_flag & PV_IS_LOCAL) {
 		struct task_struct *task = PVP(vp)->pvp_pproc;
 
@@ -981,6 +1022,7 @@
 			return oom_adjust_write((struct file *)task, buf, count, ppos);
 	} else
 		return -EREMOTE;
+#endif
 }
 
 static ssize_t ssi_oom_adjust_read(struct file *file, char *buf,
@@ -1016,6 +1058,9 @@
 
 #ifdef CONFIG_AUDITSYSCALL
 #define TMPBUFLEN 21
+#ifdef CONFIG_VPROC
+#error not yet supported
+#endif
 static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
 				  size_t count, loff_t *ppos)
 {
@@ -1138,9 +1183,11 @@
 }
 
 #ifdef CONFIG_SSI
+#ifndef PROC_CLUSTER_DIR_ENTRY_FIX
 /*
  * FIXME SSI_XXX The base version takes big kernel lock. May need further look
  */
+#endif
 static int ssi_proc_pid_readlink(struct dentry * dentry, char __user * buffer, int buflen)
 {
 	int error = -EACCES;
@@ -1187,7 +1234,7 @@
 	unlock_kernel();
 	return error;
 }
-#endif
+#endif /* !CONFIG_SSI */
 
 static struct inode_operations proc_pid_link_inode_operations = {
 #ifdef CONFIG_SSI
@@ -1342,7 +1389,7 @@
 
 	ret = 0;
 	pid = proc_task(inode)->pid;
-#endif
+#endif /* !CONFIG_SSI */
 	i = filp->f_pos;
 	switch (i) {
 	case 0:
@@ -1415,9 +1462,7 @@
 
 
 #ifdef CONFIG_SSI
-/* Callers must hold VPROC movement
- * with the exception of when the pid is migrating in.
- */
+/* Called with VPROC_HOLD_MOVEMENT on vproc. */
 static struct inode *
 proc_pid_make_inode(struct super_block * sb, struct vproc *vp, int ino, int *tgid)
 #else
@@ -1487,12 +1532,25 @@
 			 */
 			if (PVPOP_PROCFS_GETATTR(vp, 0, 0, &dumpable, &euid, &egid, tgid))
 				goto out_unlock;
+#ifdef TASK_HOLD_VPROC
+			task = NULL;
+#endif
 		}
 	}
 
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->i_ino = fake_ino(vp->vp_pid, ino);
 
+#ifdef TASK_HOLD_VPROC
+	/* RT: Prevent proc_dentry dput() modifying bogus task_struct
+	 * due to migration.
+	 */
+	/* grab the reference to task. */
+	if (task) {
+		get_task_struct(task);
+		ei->task = task;
+	}
+#endif
 	/*
 	 * grab the reference to vproc.
 	 */
@@ -1509,7 +1567,7 @@
 	if (task)
 		security_task_to_inode(task, inode);
 #endif
-#else
+#else /* !CONFIG_SSI */
 	ei->task = NULL;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->i_ino = fake_ino(task->pid, ino);
@@ -1530,7 +1588,7 @@
 		inode->i_gid = task->egid;
 	}
 	security_task_to_inode(task, inode);
-#endif
+#endif /* !CONFIG_SSI */
 
 out:
 	return inode;
@@ -1543,6 +1601,22 @@
 
 /* dentry stuff */
 
+#ifdef CONFIG_SSI
+/* Determine whether pid is migrating in */
+static inline int vproc_migrating(struct vproc *vp)
+{
+#ifdef TASK_HOLD_VPROC
+	/* SSI_ASSERT(current->p_vproc == vp); */
+	return (current->ppid == 2 &&
+		current->epid != vp->vp_pid &&
+		current->pid == vp->vp_pid);
+#else
+	return (current->ppid == 2 && current->p_vproc->vp_pid != vp->vp_pid &&
+			current->pid == vp->vp_pid);
+#endif
+}
+#endif /* CONFIG_SSI */
+
 /*
  *	Exceptional case: normally we are not allowed to unhash a busy
  * directory. In this case, however, we can do it - no aliasing problems
@@ -1553,21 +1627,24 @@
  */
 static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
-#ifdef CONFIG_SSI
 	struct inode *inode = dentry->d_inode;
-	struct vproc *vp = proc_vproc(dentry->d_inode);
+#ifdef CONFIG_SSI
 	int dumpable, euid, egid;
 
 	/*
 	 * If pid is migrating in then return true, 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)
+	if (vproc_migrating(proc_vproc(inode))) {
+#ifdef TASK_HOLD_VPROC
+		if (PROC_I(inode)->task == NULL)
+			goto out_bad; /* need to fill proc_dentry */
+#endif
 		return 1;
+	}
 
-	if (!PVPOP_PROCFS_GETATTR(vp, 0, 0, &dumpable, &euid, &egid, 0)) {
-		if (proc_type(inode) == PROC_TGID_INO || 
+	if (!PVPOP_PROCFS_GETATTR(proc_vproc(inode), 0, 0, &dumpable, &euid, &egid, 0)) {
+		if (proc_type(inode) == PROC_TGID_INO ||
 				proc_type(inode) == PROC_TID_INO || dumpable) {
 			inode->i_uid = euid;
 			inode->i_gid = egid;
@@ -1578,8 +1655,10 @@
 		/* security_task_to_inode(task, inode); */
 		return 1;
 	}
+#ifdef TASK_HOLD_VPROC
+out_bad:
+#endif
 #else
-	struct inode *inode = dentry->d_inode;
 	struct task_struct *task = proc_task(inode);
 	if (pid_alive(task)) {
 		if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
@@ -1650,7 +1729,7 @@
 	struct task_struct *task = proc_task(inode);
 #ifdef CONFIG_SSI
 	if (task == NULL) {
-		/* SSI_XXX remote task. */
+		/* remote task */
 		iput(inode);
 		return;
 	}
@@ -1670,14 +1749,14 @@
 	 */
 #ifdef CONFIG_SSI
 	/* For remote processes return 1, so dentry is not in cache */
-#ifdef VPROC_HOLD_ZERO_GET_TASK
+#if defined(VPROC_HOLD_ZERO_GET_TASK) && !defined(TASK_HOLD_VPROC)
 	return !PV_IS_ALIVE(PVP(proc_vproc(dentry->d_inode)));
 #else
-	return !proc_task((dentry->d_inode));
+	return (!proc_task(dentry->d_inode) || !pid_alive(proc_task(dentry->d_inode)));
 #endif
 #else
 	return !pid_alive(proc_task(dentry->d_inode));
-#endif
+#endif /* !CONFIG_SSI */
 }
 
 static struct dentry_operations tid_fd_dentry_operations =
@@ -1742,10 +1821,10 @@
 		goto out;
 #ifdef CONFIG_SSI
 	/* SSI: we let proc_pid_make_inode() perform the pid_alive() check */
-	VPROC_HOLD_MOVEMENT(proc_vproc(dir), "proc_pident_lookup");
+	VPROC_HOLD_MOVEMENT(proc_vproc(dir), "proc_lookupfd");
 
 	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");
+	VPROC_RELEASE_MOVEMENT(proc_vproc(dir), "proc_lookupfd");
 #else
 	if (!pid_alive(task))
 		goto out;
@@ -1827,6 +1906,9 @@
 };
 
 #ifdef CONFIG_SECURITY
+#ifdef CONFIG_VPROC
+#error not yet supported
+#endif
 static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
 				  size_t count, loff_t *ppos)
 {
@@ -1926,18 +2008,12 @@
 	inode = NULL;
 
 #ifdef CONFIG_SSI
-	/* SSI: we let proc_pid_make_inode() perform the pid_alive() check */
+	/* 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)))
-		goto out;
-#else
 	if (proc_vproc(dir)->vp_pid != current->pid &&
 	    !process_is_alive(proc_vproc(dir)->vp_pid))
 		goto out;
 #endif
-#endif
 #else
 	if (!pid_alive(task))
 		goto out;
@@ -2294,7 +2370,7 @@
 	int died;
 #ifdef CONFIG_SSI
 	struct vproc *vp;
-	int hold_movement = 1;
+	int hold_movement = 0;
 #endif
 
 	if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
@@ -2325,11 +2401,10 @@
 	 * 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
+	if (!vproc_migrating(vp)) {
 		VPROC_HOLD_MOVEMENT(vp, "proc_pid_lookup");
+		hold_movement = 1;
+	}
 
 #ifdef VPROC_HOLD_ZERO_GET_TASK
 	if (PVP(vp)->pvp_flag & PV_IS_LOCAL) {
@@ -2341,7 +2416,6 @@
 	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(tgid) && (tgid != 1) )) {
 			 /* 
@@ -2416,23 +2490,6 @@
 	put_task_struct(task);
 #ifdef CONFIG_SSI
 	}
-#if 0
-#ifdef VPROC_IS_ALIVE
-	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");
@@ -2449,7 +2506,9 @@
 /* SMP-safe */
 static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
+#ifndef VPROC_HOLD_ZERO_GET_TASK
 	struct task_struct *task;
+#endif
 #ifndef CONFIG_SSI
 	struct task_struct *leader = proc_task(dir);
 #endif
@@ -2472,16 +2531,13 @@
 	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) {
+		if (leader->vp_pid != PVP(vp)->pvp_pproc->tgid) {
 			VPROC_RELEASE_MOVEMENT(vp, "proc_task_lookup");
 			VPROC_RELE(vp, "proc_task_lookup");
 			goto out;
 		}
-		get_task_struct(task);
 	} else { /* remote process */
-		task = NULL;
 #else
 	task = proc_ssi_task(vp);
 	if( task == NULL ) { /* remote process */
@@ -2508,21 +2564,33 @@
 	VPROC_RELE(vp, "proc_task_lookup");
 
 	/* leader's pid should be this vproc tgid */
+#ifdef VPROC_HOLD_ZERO_GET_TASK
+	if (!inode || leader->vp_pid != tgid) {
+#else
 	if (!inode || (!task && leader->vp_pid != tgid)) {
+#endif
 #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) {
+		if (inode)
 			iput(inode);
-			goto out;
-		}
+#ifndef VPROC_HOLD_ZERO_GET_TASK
+		if (task)
+			put_task_struct(task);
 #endif
+		goto out;
+#else
+#ifdef VPROC_HOLD_ZERO_GET_TASK
+		goto out;
+#else
 		goto out_drop_task;
+#endif
+#endif /* !PROC_TASK_LOOKUP_FIX */
 	}
-#else
+#else /* !CONFIG_SSI */
 
 
 	read_lock(&tasklist_lock);
@@ -2540,7 +2608,7 @@
 
 	if (!inode)
 		goto out_drop_task;
-#endif
+#endif /* !CONFIG_SSI */
 	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
 	inode->i_op = &proc_tid_base_inode_operations;
 	inode->i_fop = &proc_tid_base_operations;
@@ -2552,12 +2620,18 @@
 	d_add(dentry, inode);
 
 #ifdef CONFIG_SSI
+#ifndef VPROC_HOLD_ZERO_GET_TASK
 	if( task )
+		put_task_struct(task);
 #endif
+#else
 	put_task_struct(task);
+#endif /* !CONFIG_SSI */
 	return NULL;
+#ifndef CONFIG_SSI
 out_drop_task:
 	put_task_struct(task);
+#endif
 out:
 	return ERR_PTR(-ENOENT);
 }
@@ -2750,18 +2824,13 @@
 #ifndef VPROC_HOLD_ZERO_GET_TASK
 	task_t *task = NULL;
 #endif
-	u_int *tids;
+	u_int *tids = NULL;
 
 	/* SSI: we skip possible remote pid_alive() check here */
 #if 0
-#ifdef VPROC_IS_ALIVE
-	if (!vproc_is_alive(proc_vproc(inode)))
-		goto out;
-#else
 	if (!process_is_alive(proc_vproc(inode)->vp_pid))
 		goto out;
 #endif
-#endif
 #else
 	if (!pid_alive(proc_task(inode)))
 		goto out;
@@ -2789,19 +2858,23 @@
 	task = proc_ssi_task(vp);
 	if ( !PVP(current->p_vproc)->pvp_localview || !task) {
 #else
-	if (!PVP(current->p_vproc)->pvp_localview ||
-	    !(PVP(vp)->pvp_flag & PV_IS_LOCAL)) {
+	if (!(PVP(vp)->pvp_flag & PV_IS_LOCAL)) {
 #endif
-		int len;
+		int len = PROC_MAXPIDS;
 		/*
 		 * remote listing
 		 */
 		/* 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 {
+#ifdef TASK_HOLD_VPROC
+		if (!PV_IS_ALIVE(PVP(vp))) {
+			VPROC_RELEASE_MOVEMENT(vp, "proc_task_readdir");
+			goto out;
+		}
+#endif
 		nr_tids = get_tid_list(pos, tid_array, inode);
 #ifndef VPROC_HOLD_ZERO_GET_TASK
 		put_task_struct(task);
@@ -2810,7 +2883,7 @@
 	VPROC_RELEASE_MOVEMENT(vp, "proc_task_readdir");
 #else
 	nr_tids = get_tid_list(pos, tid_array, inode);
-#endif
+#endif /* !CONFIG_SSI */
 
 	for (i = 0; i < nr_tids; i++) {
 		unsigned long j = PROC_NUMBUF;
@@ -2832,6 +2905,7 @@
 }
 
 #ifdef CONFIG_SSI
+/* Called with VPROC movement held */
 int ssi_get_tid_list(struct task_struct *p, int index, int *tids)
 {
 	struct inode *inode = NULL;
@@ -2860,9 +2934,7 @@
 
 #ifdef VPROC_HOLD_ZERO_GET_TASK
 	ttynode = 0;
-	VPROC_LOCK_FLAG(task->p_vproc, "proc_pid_ttynode");
 	(void) pproc_getctty(task, NULL, &ttynode);
-	VPROC_UNLOCK_FLAG(task->p_vproc, "proc_pid_ttynode");
 #else
 	ttynode = task->signal->cttynode;
 #endif
@@ -2880,18 +2952,26 @@
 #ifdef CONFIG_LDLVL
 int proc_pid_loadlevel(struct task_struct *task, char * buffer)
 {
-	struct pvproc *pvp = PVP(task->p_vproc);
+	struct vproc *vp = task->p_vproc;
+#ifdef TASK_HOLD_VPROC
+	extern int vproc_is_loadlevelable(struct vproc *, char *);
+#else
 	extern int is_loadlevelable(struct task_struct *, char *);
+#endif
 
-	sprintf(buffer,"%lu\n",pvp->pvp_loadlevel < 0 ?
+	sprintf(buffer,"%lu\n", PVP(vp)->pvp_loadlevel < 0 ?
+#ifdef TASK_HOLD_VPROC
+						vproc_is_loadlevelable(vp, NULL) :
+#else
 						is_loadlevelable(task, NULL) :
-						pvp->pvp_loadlevel);
+#endif
+						PVP(vp)->pvp_loadlevel);
 	return (strlen(buffer));
 }
 #endif
 
 /*
- *This need to be called by holding the generic lock
+ * SSI_XXX: This need to be called by holding the generic lock
  *ie , VPROC_LOCK_EXCL(task->p_vproc, "proc_pid_pin")
  */
 int proc_pid_pin(struct task_struct *task, char * buffer)
@@ -2922,6 +3002,7 @@
 	return (strlen(buffer));
 }
 
+/* Called with VPROC movement held */
 ssize_t do_ssi_write(struct task_struct *task, char * buf,
 			size_t count, loff_t *ppos, int type)
 {
@@ -2957,6 +3038,9 @@
 					&& !capable(CAP_KILL))
 				return -EACCES;
 
+#ifndef TASK_HOLD_VPROC
+#warning disables move_eligible_processes_off()
+#endif
 			/* Silently fail if a kernel daemon. */
 			if (task->mm == NULL)
 				return count;
@@ -3023,15 +3107,93 @@
 	return result;
 }
 
+#ifdef TASK_HOLD_VPROC
+/* TODO: use PVPOP_MIGRATE */
+int
+vproc_migrate_local(struct vproc *v, clusternode_t node)
+{
+	struct pvproc *pvp = PVP(v);
+	int ret;
+
+	if (!PV_IS_ALIVE(pvp) || (pvp->pvp_flag & PV_EXITING))
+		return -EINVAL;
+
+	ret = VPROC_HOLD_MOVEMENT_LOCAL(v, "vproc_migrate_local");
+	if (ret == -EREMOTE)
+		return ret;
+	SSI_ASSERT(ret == ESUCCESS);
+
+	if (PV_IS_ALIVE(pvp) && !(pvp->pvp_pproc->flags & PF_EXITING)) {
+		(void) setup_execnode_move(pvp->pvp_pproc, node, MOV_SIGMIG);
+	} else
+		ret = -EINVAL;
+
+	VPROC_RELEASE_MOVEMENT(v, "vproc_migrate_local");
+	return ret;
+}
+
+void __deprecated
+vproc_migrate(struct vproc *vp, clusternode_t node)
+{
+	mm_segment_t old_fs;
+	loff_t dummy = 0;
+	int nlen, ret;
+	char nstr[16];
+#ifdef CONFIG_LDLVL
+	extern void unchoose_me(struct task_struct *);
+#endif
+
+	if (PVP(vp)->pvp_flag & PV_EXITING)
+		return;
+
+	nlen = snprintf(nstr, sizeof(nstr), "%ld\n", (long)node);
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = PVPOP_PROCFS_WRITE(vp, nstr, nlen, &dummy, PROC_TGID_GOTO);
+
+	set_fs(old_fs);
+	if (ret != nlen) {
+		if (!(PVP(vp)->pvp_flag & PV_EXITING))
+			printk(KERN_WARNING
+			"proc_migrate: migrate to process %d returned %d\n",
+			vp->vp_pid, ret);
+#ifdef CONFIG_LDLVL
+		unchoose_me(PVP(vp)->pvp_pproc);
+#endif
+	}
+}
+#endif /* TASK_HOLD_VPROC */
+
 void
+#ifdef TASK_HOLD_VPROC
+__deprecated
+#endif
 proc_migrate(struct task_struct *p, clusternode_t node)
 {
+#ifdef TASK_HOLD_VPROC
+	struct vproc *vp = p->p_vproc;
+#ifdef CONFIG_LDLVL
+	extern void unchoose_me(struct task_struct *);
+#endif
+
+	if (!p->pid || !VPROC_HOLD_AND_CHECK(vp, "proc_migrate")) {
+#ifdef CONFIG_LDLVL
+		unchoose_me(p);
+#endif
+		return;
+	}
+
+	vproc_migrate(vp, node);
+#else /* !TASK_HOLD_VPROC */
 	char nstr[16];
 	int nlen;
 	int ret;
 	mm_segment_t old_fs;
 	struct vproc *vp = p->p_vproc;
+#ifdef CONFIG_LDLVL
 	extern void unchoose_me(struct task_struct *);
+#endif
 	loff_t dummy = 0;
 
 	if (!p->pid || !vp) {
@@ -3055,10 +3217,11 @@
 		unchoose_me(p);
 #endif
 	}
+#endif /* !TASK_HOLD_VPROC */
 	VPROC_RELE(vp, "proc_migrate");
 }
 
-
+/* Called with VPROC movement held */
 int
 do_proc_info(struct task_struct *task, int type, char *buffer)
 {
@@ -3112,6 +3275,7 @@
 	return -EINVAL;
 }
 
+/* Called with VPROC movement held */
 int
 do_proc_links(struct vproc *vp, int type, char *buffer, int buflen,
 	      struct dentry **dentry, struct vfsmount **vfsmnt)

Index: inode.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/inode.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- inode.c	7 Aug 2007 03:06:13 -0000	1.12
+++ inode.c	27 Oct 2009 03:18:30 -0000	1.13
@@ -64,20 +64,19 @@
 static void proc_delete_inode(struct inode *inode)
 {
 	struct proc_dir_entry *de;
+	struct task_struct *tsk;
 #ifdef CONFIG_SSI
 	struct vproc *vp;
 
 	vp = PROC_I(inode)->vproc;
 	if (vp)
 		VPROC_RELE(vp, "proc_delete_inode");
-#else
-	struct task_struct *tsk;
+#endif
 
 	/* Let go of any associated process */
 	tsk = PROC_I(inode)->task;
 	if (tsk)
 		put_task_struct(tsk);
-#endif
 
 	/* Let go of any associated proc directory entry */
 	de = PROC_I(inode)->pde;
@@ -108,9 +107,8 @@
 		return NULL;
 #ifdef CONFIG_SSI
 	ei->vproc = NULL;
-#else
-	ei->task = NULL;
 #endif
+	ei->task = NULL;
 	ei->type = 0;
 	ei->op.proc_get_link = NULL;
 	ei->pde = NULL;

Index: proc_cluster.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/proc_cluster.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- proc_cluster.c	24 Mar 2009 04:26:29 -0000	1.15
+++ proc_cluster.c	27 Oct 2009 03:18:30 -0000	1.16
@@ -53,7 +53,8 @@
 
 #define PROC_CLUSTER_NODELIST_END \
 		node = NSC_NODELIST_GET_NEXT(&cookie,nodelist); \
-	}
+	} \
+	NSC_NODELIST_FREE(nodelist)
 
 #ifdef CONFIG_LDLVL
 static int
@@ -218,7 +219,7 @@
 	node = (clusternode_t)de->data;
 	if (node == this_node)
 		sprintf((char *)page, "%d\n",
-				(loadlvl_enabled ? loadlevel_on : -1));
+				(loadlvl_enabled ? atomic_read(&loadlevel_on) : -1));
 	else
 		sprintf((char *)page, "%d\n",
 				(loadinfo[node].mem == 0 ? 0 : 1));

Index: internal.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/internal.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- internal.h	24 Mar 2009 04:26:29 -0000	1.4
+++ internal.h	27 Oct 2009 03:18:30 -0000	1.5
@@ -66,7 +66,7 @@
 	return task;
 }
 #endif /* !VPROC_HOLD_ZERO_GET_TASK */
-#endif
+#endif /* CONFIG_SSI */
 
 extern void create_seq_entry(char *name, mode_t mode, struct file_operations *f);
 extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **);
@@ -77,9 +77,9 @@
 
 static inline struct task_struct *proc_task(struct inode *inode)
 {
-#ifdef CONFIG_SSI
-        struct vproc *vp = proc_vproc(inode);
-        return (PVP(vp)->pvp_pproc);
+#if defined(CONFIG_SSI) && !defined(TASK_HOLD_VPROC)
+	/* Called with VPROC LOCK locked or VPROC movement held */
+        return PVP(proc_vproc(inode))->pvp_pproc;
 #else
 	return PROC_I(inode)->task;
 #endif


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
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.