[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