summaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c30
-rw-r--r--fs/proc/base.c2
-rw-r--r--fs/proc/fd.c4
-rw-r--r--fs/proc/inode.c8
-rw-r--r--fs/proc/mem.c2
-rw-r--r--fs/proc/root.c12
6 files changed, 48 insertions, 10 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 5364cea14..33df2c56a 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -446,7 +446,11 @@ static int get_array(struct task_struct *p, unsigned long start, unsigned long e
static int get_env(int pid, char * buffer)
{
- struct task_struct *p = find_task_by_pid(pid);
+ struct task_struct *p;
+
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!p || !p->mm)
return 0;
@@ -455,8 +459,11 @@ static int get_env(int pid, char * buffer)
static int get_arg(int pid, char * buffer)
{
- struct task_struct *p = find_task_by_pid(pid);
+ struct task_struct *p;
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!p || !p->mm)
return 0;
return get_array(p, p->mm->arg_start, p->mm->arg_end, buffer);
@@ -781,8 +788,11 @@ static inline char * task_sig(struct task_struct *p, char *buffer)
static int get_status(int pid, char * buffer)
{
char * orig = buffer;
- struct task_struct *tsk = find_task_by_pid(pid);
+ struct task_struct *tsk;
+ read_lock(&tasklist_lock);
+ tsk = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!tsk)
return 0;
buffer = task_name(tsk, buffer);
@@ -794,7 +804,7 @@ static int get_status(int pid, char * buffer)
static int get_stat(int pid, char * buffer)
{
- struct task_struct *tsk = find_task_by_pid(pid);
+ struct task_struct *tsk;
unsigned long vsize, eip, esp, wchan;
long priority, nice;
int tty_pgrp;
@@ -805,6 +815,9 @@ static int get_stat(int pid, char * buffer)
char sigcatch_str[sizeof(sigset_t)*2+1];
char state;
+ read_lock(&tasklist_lock);
+ tsk = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!tsk)
return 0;
state = *get_task_state(tsk);
@@ -959,6 +972,9 @@ static int get_statm(int pid, char * buffer)
struct task_struct *tsk = find_task_by_pid(pid);
int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
+ read_lock(&tasklist_lock);
+ tsk = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!tsk)
return 0;
if (tsk->mm && tsk->mm != &init_mm) {
@@ -1041,7 +1057,9 @@ static ssize_t read_maps (int pid, struct file * file, char * buf,
goto out;
retval = -EINVAL;
+ read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (!p)
goto freepage_out;
@@ -1152,9 +1170,11 @@ static int get_pidcpu(int pid, char * buffer)
{
struct task_struct * tsk = current ;
int i, len;
-
+
+ read_lock(&tasklist_lock);
if (pid != tsk->pid)
tsk = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */
if (tsk == NULL)
return 0;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index dc182682a..e535276bb 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -60,12 +60,14 @@ static void proc_pid_fill_inode(struct inode * inode, int fill)
int pid = inode->i_ino >> 16;
int ino = inode->i_ino & 0xffff;
+ read_lock(&tasklist_lock);
if (fill && (p = find_task_by_pid(pid)) != NULL) {
if (p->dumpable || ino == PROC_PID_INO) {
inode->i_uid = p->euid;
inode->i_gid = p->gid;
}
}
+ read_unlock(&tasklist_lock);
}
/*
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 4baa299fc..8897578d6 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -96,7 +96,9 @@ static int proc_lookupfd(struct inode * dir, struct dentry * dentry)
break;
}
}
+ read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done only after not using 'p' any more */
if (!pid || !p)
return -ENOENT;
@@ -149,7 +151,9 @@ static int proc_readfd(struct file * filp,
return 0;
}
+ read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done only after not using 'p' any more */
if(!p)
return 0;
tarrayp = p->tarray_ptr;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index c33616604..9a0e29a84 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -260,7 +260,13 @@ void proc_read_inode(struct inode * inode)
inode->i_size = 0;
pid = ino >> 16;
- if (!pid || ((p = find_task_by_pid(pid)) == NULL))
+ if (!pid)
+ return;
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!! This should be done only after we have stopped using 'p' */
+
+ if (!p)
return;
ino &= 0x0000ffff;
diff --git a/fs/proc/mem.c b/fs/proc/mem.c
index c49f187c0..1cbdbad9a 100644
--- a/fs/proc/mem.c
+++ b/fs/proc/mem.c
@@ -83,7 +83,9 @@ static ssize_t mem_read(struct file * file, char * buf,
char *tmp;
ssize_t scount, i;
+ read_lock(&tasklist_lock);
tsk = get_task(inode->i_ino >> 16);
+ read_unlock(&tasklist_lock); /* FIXME: This should really be done only afetr not using tsk any more!!! */
if (!tsk)
return -ESRCH;
addr = *ppos;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 3e344bd09..ad3a541cb 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -14,8 +14,8 @@
#include <linux/stat.h>
#include <linux/config.h>
#include <asm/bitops.h>
-#ifdef CONFIG_KERNELD
-#include <linux/kerneld.h>
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
#endif
/*
@@ -234,7 +234,7 @@ proc_openprom_deregister(void)
}
#endif
-#if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KERNELD)
+#if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KMOD)
static int
proc_openprom_defreaddir(struct inode * inode, struct file * filp,
void * dirent, filldir_t filldir)
@@ -812,14 +812,18 @@ static int proc_root_lookup(struct inode * dir, struct dentry * dentry)
break;
}
}
+ read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
inode = NULL;
if (pid && p) {
unsigned long ino = (pid << 16) + PROC_PID_INO;
inode = proc_get_inode(dir->i_sb, ino, &proc_pid);
- if (!inode)
+ if (!inode) {
+ read_unlock(&tasklist_lock);
return -EINVAL;
+ }
}
+ read_unlock(&tasklist_lock);
dentry->d_op = &proc_dentry_operations;
d_add(dentry, inode);