[SSI] openssi/kernel/fs/proc base.c,1.32,1.33

Roger Tsang <[email protected]> Mon, 17 Jan 2011 07:00:30 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/fs/proc
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv784/fs/proc

Modified Files:
      Tag: OPENSSI-FC
	base.c 
Log Message:
- proc_pid_make_inode, proc_pid_lookup, proc_task_lookup: Use revised proc_ssi_task(). Avoid VPROC MOVEMENT LOCK since we could be in time-critical VFS lookup code path. Avoid waiting for process migration.
- proc_pid_make_inode: reduce redundant code.
- proc_pident_lookup, proc_lookupfd: No need to acquire VPROC MOVEMENT LOCK for revised proc_pid_make_inode().
- proc_task_readdir: no need for seperate code path for local listing. remove redundant.
- vproc_migrate_local: no need to acquire VPROC MOVEMENT LOCK since setup_execnode_move() will check move header list for existing entries.

(#ifdef TASK_HOLD_VPROC)
- proc_permission, ssi_mounts_open, ssi_oom_adjust: no need to acquire VPROC MOVEMENT LOCK since the caller holds inode reference which means the task_struct reference held by PROC_I()->task is safe against concurrent process migration.
- oom_adjust_read, oom_adjust_write: remove ugly type casting. caller ensures PROC_I()->task is valid.


Index: base.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/fs/proc/base.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- base.c	15 Dec 2010 06:53:20 -0000	1.32
+++ base.c	17 Jan 2011 07:00:28 -0000	1.33
@@ -506,22 +506,11 @@
 
 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;
+	return (!proc_task(inode)) ? 0 : proc_check_root(inode);
 #else
 	/* 
 	 * FIXME!! SSI_XXX Why do we skip the below proc_check_root ? 
@@ -646,31 +635,13 @@
 {
 	int error;
 	struct nameidata nd;
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	struct task_struct *task = proc_ssi_task(proc_vproc(inode));
 
-	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);
+	if (proc_task(inode))
+		return mounts_open(inode, file);
 #else
-#ifdef TASK_HOLD_VPROC
-		VPROC_RELEASE_MOVEMENT(vp, "ssi_mounts_open");
-#endif
+#error deprecated. pls define TASK_HOLD_VPROC
 #endif
-		return ret;
-	}
 
 	/* SSI_XXX: Process is remote...however since we currently dont
 	 * support private namespaces, there is no need to go to the
@@ -943,11 +914,7 @@
 static ssize_t oom_adjust_read(struct file *file, char *buf,
 				size_t count, loff_t *ppos)
 {
-#ifndef CONFIG_SSI
 	struct task_struct *task = proc_task(file->f_dentry->d_inode);
-#else
-	struct task_struct *task = (struct task_struct *)file;
-#endif
 	char buffer[8];
 	size_t len;
 	int oom_adjust = task->oomkilladj;
@@ -967,11 +934,7 @@
 static ssize_t oom_adjust_write(struct file *file, const char *buf,
 				size_t count, loff_t *ppos)
 {
-#ifndef CONFIG_SSI
 	struct task_struct *task = proc_task(file->f_dentry->d_inode);
-#else
-	struct task_struct *task = (struct task_struct *)file;
-#endif
 	char buffer[8], *end;
 	int oom_adjust;
 
@@ -997,22 +960,18 @@
 static ssize_t ssi_oom_adjust(struct file *file, char *buf,
 				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)
+	if (!proc_task(file->f_dentry->d_inode))
 		return -EREMOTE;
 
 	if (!type)
-		ret = oom_adjust_read((struct file *) PVP(vp)->pvp_pproc, buf, count, ppos);
+		return oom_adjust_read(file, 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;
+		return oom_adjust_write(file, buf, count, ppos);
 #else
+#error deprecated. use TASK_HOLD_VPROC
+	struct vproc *vp = proc_vproc(file->f_dentry->d_inode);
+
 	if (PVP(vp)->pvp_flag & PV_IS_LOCAL) {
 		struct task_struct *task = PVP(vp)->pvp_pproc;
 
@@ -1464,7 +1423,6 @@
 
 
 #ifdef CONFIG_SSI
-/* 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
@@ -1488,70 +1446,50 @@
 	ei = PROC_I(inode);
 
 #ifdef CONFIG_SSI
-	if (PVP(vp)->pvp_flag & PV_IS_LOCAL) {
-#ifdef VPROC_HOLD_ZERO_GET_TASK
-		task = PVP(vp)->pvp_pproc;
-
-		if (!pid_alive(task))
-			goto out_unlock;
-#else
-		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);
-
-		if (tgid)
-			*tgid = task->tgid;
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-		put_task_struct(task);
-#endif
-	} else {
-		if (current->pid == vp->vp_pid) {
+	task = proc_ssi_task(vp);
+	if (task || vproc_migrating(vp)) {
+		if (!task) {
 			/* 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.
 			 */
 			task = current;
-			euid = task->euid;
-			egid = task->egid;
+			get_task_struct(task);
 			dumpable = 1;
-			if (tgid)
-				*tgid = task->tgid;
 		} else {
-			/*
-			 * Task on remote node. Get the attributes from remote 
-			 * node
-			 */
-			if (PVPOP_PROCFS_GETATTR(vp, 0, 0, &dumpable, &euid, &egid, tgid))
+			if (!pid_alive(task)) {
+				put_task_struct(task);
 				goto out_unlock;
-#ifdef TASK_HOLD_VPROC
-			task = NULL;
-#endif
+			}
+			dumpable = task_dumpable(task);
 		}
+		euid = task->euid;
+		egid = task->egid;
+		if (tgid)
+			*tgid = task->tgid;
+#ifndef TASK_HOLD_VPROC
+		put_task_struct(task);
+#endif
+	} else {
+		/*
+		 * Task on remote node. Get the attributes from remote
+		 * node
+		 */
+		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(vp->vp_pid, ino);
 
+	SSI_ASSERT(ei->task == NULL);
 #ifdef TASK_HOLD_VPROC
-	/* RT: Prevent proc_dentry dput() modifying bogus task_struct
-	 * due to migration.
+	/* Prevent proc_dentry dput() modifying bogus task_struct
+	 * due to migration.	-Roger
 	 */
-	/* grab the reference to task. */
-	if (task) {
-		get_task_struct(task);
+	if (task)
 		ei->task = task;
-	}
 #endif
 	/*
 	 * grab the reference to vproc.
@@ -1566,6 +1504,7 @@
 		inode->i_gid = egid;
 	}
 #if 0
+	/* TODO: clustered security infrastructure */
 	if (task)
 		security_task_to_inode(task, inode);
 #endif
@@ -1603,22 +1542,6 @@
 
 /* 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
@@ -1823,10 +1746,7 @@
 		goto out;
 #ifdef CONFIG_SSI
 	/* SSI: we let proc_pid_make_inode() perform the pid_alive() check */
-	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_lookupfd");
 #else
 	if (!pid_alive(task))
 		goto out;
@@ -2030,11 +1950,7 @@
 
 	error = -EINVAL;
 #ifdef CONFIG_SSI
-	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
@@ -2380,7 +2296,6 @@
 	int died;
 #ifdef CONFIG_SSI
 	struct vproc *vp;
-	int hold_movement = 0;
 #endif
 
 	if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
@@ -2407,25 +2322,8 @@
 	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 (!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) {
-		task = PVP(vp)->pvp_pproc;
-		get_task_struct(task);
-	} else { /* remote process */
-		task = NULL;
-#else
 	task = proc_ssi_task(vp);
-	if( task == NULL ) { /* remote process */
-#endif /* !VPROC_HOLD_ZERO_GET_TASK */
+	if (task == NULL) { /* remote process */
 #ifdef TASK_HOLD_VPROC
 		if ((current->p_vproc && PVP(current->p_vproc)->pvp_localview == 1) ||
 		    (!PIDNODE(tgid) && tgid != 1)) {
@@ -2441,20 +2339,15 @@
 			  * 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, vp, PROC_TGID_INO, NULL);
-
-	if (!inode ) {
+	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;
 
@@ -2475,7 +2368,7 @@
 		put_task_struct(task);
 		goto out;
 	}
-#endif
+#endif /* !CONFIG_SSI */
 	inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
 	inode->i_op = &proc_tgid_base_inode_operations;
 	inode->i_fop = &proc_tgid_base_operations;
@@ -2505,8 +2398,6 @@
 	put_task_struct(task);
 #ifdef CONFIG_SSI
 	}
-	if (hold_movement)
-		VPROC_RELEASE_MOVEMENT(vp, "proc_pid_lookup");
 	VPROC_RELE(vp, "proc_pid_lookup");
 #endif /* CONFIG_SSI */
 	if (died) {
@@ -2521,10 +2412,8 @@
 /* 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 *task;
 	struct task_struct *leader = proc_task(dir);
 #endif
 	struct inode *inode;
@@ -2543,20 +2432,7 @@
 	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) {
-		/* leader's pid should be this vproc 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;
-		}
-	} else { /* remote process */
-#else
-	task = proc_ssi_task(vp);
-	if( task == NULL ) { /* remote process */
-#endif /* !VPROC_HOLD_ZERO_GET_TASK */
+	if (!(PVP(vp)->pvp_flag & PV_IS_LOCAL)) {
 		 if (PVP(current->p_vproc)->pvp_localview == 1 ||
 				 ( !PIDNODE(tid) && (tid != 1) )) {
 			 /* 
@@ -2567,23 +2443,16 @@
 			  * 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, vp, PROC_TID_INO, &tgid);
-
-	VPROC_RELEASE_MOVEMENT(vp, "proc_task_lookup");
 	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
@@ -2592,20 +2461,10 @@
 		 */
 		if (inode)
 			iput(inode);
-#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 */
+		goto out;
 	}
-#else /* !CONFIG_SSI */
+#else /* CONFIG_SSI */
 
 
 	read_lock(&tasklist_lock);
@@ -2634,12 +2493,7 @@
 
 	d_add(dentry, inode);
 
-#ifdef CONFIG_SSI
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	if( task )
-		put_task_struct(task);
-#endif
-#else
+#ifndef CONFIG_SSI
 	put_task_struct(task);
 #endif /* !CONFIG_SSI */
 	return NULL;
@@ -2823,10 +2677,8 @@
 
 #ifdef CONFIG_SSI
 	struct vproc *vp = proc_vproc(inode);
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	task_t *task = NULL;
-#endif
-	u_int *tids = NULL;
+	u_int *tids = tid_array;
+	int len = PROC_MAXPIDS;
 
 	/* SSI: we skip possible remote pid_alive() check here */
 #if 0
@@ -2855,34 +2707,7 @@
 	}
 
 #ifdef CONFIG_SSI
-	VPROC_HOLD_MOVEMENT(vp, "proc_task_readdir");
-#ifndef VPROC_HOLD_ZERO_GET_TASK
-	task = proc_ssi_task(vp);
-	if ( !PVP(current->p_vproc)->pvp_localview || !task) {
-#else
-	if (!(PVP(vp)->pvp_flag & PV_IS_LOCAL)) {
-#endif
-		int len = PROC_MAXPIDS;
-		/*
-		 * remote listing
-		 */
-		/* VPROC_HOLD(vp, "proc_task_readdir"); */
-		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);
-#endif
-	}
-	VPROC_RELEASE_MOVEMENT(vp, "proc_task_readdir");
+	nr_tids = PVPOP_PROCFS_TID_LIST(vp, pos, &tids, &len);
 #else
 	nr_tids = get_tid_list(pos, tid_array, inode);
 #endif /* !CONFIG_SSI */
@@ -3114,27 +2939,23 @@
 }
 
 #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);
+	task_t *task;
+	int ret = -EINVAL;
 
-	if (PV_IS_ALIVE(pvp) && !(pvp->pvp_pproc->flags & PF_EXITING)) {
-		(void) setup_execnode_move(pvp->pvp_pproc, node, MOV_SIGMIG);
-	} else
-		ret = -EINVAL;
+	task = proc_ssi_task(v);
+	if (!task)
+		return -EREMOTE;
+	if ((task->flags & PF_EXITING) || !pid_alive(task))
+		goto out;
 
-	VPROC_RELEASE_MOVEMENT(v, "vproc_migrate_local");
+	ret = setup_execnode_move(task, node, MOV_SIGMIG);
+	if (ret > 0)
+		ret = 0;
+out:
+	put_task_struct(task);
 	return ret;
 }
 


------------------------------------------------------------------------------
Protect Your Site and Customers from Malware Attacks
Learn about various malware tactics and how to avoid them. Understand 
malware threats, the impact they can have on your business, and how you 
can protect your company and customers by using code signing.
http://p.sf.net/sfu/oracle-sfdevnl