patch-2.2.1 linux/fs/proc/array.c
Next file: linux/include/asm-i386/page.h
Previous file: linux/fs/nfsd/vfs.c
Back to the patch index
Back to the overall index
- Lines: 403
- Date:
Thu Jan 28 10:08:53 1999
- Orig file:
v2.2.0/linux/fs/proc/array.c
- Orig date:
Mon Jan 25 17:44:34 1999
diff -u --recursive --new-file v2.2.0/linux/fs/proc/array.c linux/fs/proc/array.c
@@ -24,7 +24,7 @@
* <Jeff_Tranter@Mitel.COM>
*
* Bruno Haible : remove 4K limit for the maps file
- * <haible@ma2s2.mathematik.uni-karlsruhe.de>
+ * <haible@ma2s2.mathematik.uni-karlsruhe.de>
*
* Yves Arrouye : remove removal of trailing spaces in get_array.
* <Yves.Arrouye@marin.fdn.fr>
@@ -42,8 +42,6 @@
* Alan Cox : security fixes.
* <Alan.Cox@linux.org>
*
- * Andi Kleen : Race Fixes.
- *
*/
#include <linux/types.h>
@@ -388,46 +386,21 @@
return sprintf(buffer, "%s\n", saved_command_line);
}
-/*
- * Caller must release_mm the mm_struct later.
- * You don't get any access to init_mm.
- */
-static struct mm_struct *get_mm_and_lock(int pid)
-{
- struct mm_struct *mm = NULL;
- struct task_struct *tsk;
-
- read_lock(&tasklist_lock);
- tsk = find_task_by_pid(pid);
- if (tsk && tsk->mm && tsk->mm != &init_mm)
- mmget(mm = tsk->mm);
- read_unlock(&tasklist_lock);
- if (mm != NULL)
- down(&mm->mmap_sem);
- return mm;
-}
-
-static void release_mm(struct mm_struct *mm)
-{
- up(&mm->mmap_sem);
- mmput(mm);
-}
-
-static unsigned long get_phys_addr(struct mm_struct *mm, unsigned long ptr)
+static unsigned long get_phys_addr(struct task_struct * p, unsigned long ptr)
{
pgd_t *page_dir;
pmd_t *page_middle;
pte_t pte;
- if (ptr >= TASK_SIZE)
+ if (!p || !p->mm || ptr >= TASK_SIZE)
return 0;
/* Check for NULL pgd .. shouldn't happen! */
- if (!mm->pgd) {
- printk(KERN_DEBUG "missing pgd for mm %p\n", mm);
+ if (!p->mm->pgd) {
+ printk("get_phys_addr: pid %d has NULL pgd!\n", p->pid);
return 0;
}
- page_dir = pgd_offset(mm,ptr);
+ page_dir = pgd_offset(p->mm,ptr);
if (pgd_none(*page_dir))
return 0;
if (pgd_bad(*page_dir)) {
@@ -449,7 +422,7 @@
return pte_page(pte) + (ptr & ~PAGE_MASK);
}
-static int get_array(struct mm_struct *mm, unsigned long start, unsigned long end, char * buffer)
+static int get_array(struct task_struct *p, unsigned long start, unsigned long end, char * buffer)
{
unsigned long addr;
int size = 0, result = 0;
@@ -458,7 +431,7 @@
if (start >= end)
return result;
for (;;) {
- addr = get_phys_addr(mm, start);
+ addr = get_phys_addr(p, start);
if (!addr)
return result;
do {
@@ -480,28 +453,27 @@
static int get_env(int pid, char * buffer)
{
- struct mm_struct *mm;
- int res = 0;
+ 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 */
- mm = get_mm_and_lock(pid);
- if (mm) {
- res = get_array(mm, mm->env_start, mm->env_end, buffer);
- release_mm(mm);
- }
- return res;
+ if (!p || !p->mm)
+ return 0;
+ return get_array(p, p->mm->env_start, p->mm->env_end, buffer);
}
static int get_arg(int pid, char * buffer)
{
- struct mm_struct *mm;
- int res = 0;
+ struct task_struct *p;
- mm = get_mm_and_lock(pid);
- if (mm) {
- res = get_array(mm, mm->arg_start, mm->arg_end, buffer);
- release_mm(mm);
- }
- return res;
+ 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);
}
/*
@@ -606,7 +578,7 @@
#ifdef __sparc_v9__
bias = STACK_BIAS;
#endif
- fp = p->tss.ksp + bias;
+ fp = p->tss.ksp + bias;
do {
/* Bogus frame pointer? */
if (fp < (task_base + sizeof(struct task_struct)) ||
@@ -642,7 +614,7 @@
#define KSTK_EIP(tsk) \
({ \
unsigned long eip = 0; \
- if ((tsk)->tss.esp0 > PAGE_SIZE && \
+ if ((tsk)->tss.esp0 > PAGE_SIZE && \
MAP_NR((tsk)->tss.esp0) < max_mapnr) \
eip = ((struct pt_regs *) (tsk)->tss.esp0)->pc; \
eip; })
@@ -754,14 +726,11 @@
{
struct mm_struct * mm = p->mm;
- if (!mm)
- return buffer;
- if (mm != &init_mm) {
- struct vm_area_struct * vma;
+ if (mm && mm != &init_mm) {
+ struct vm_area_struct * vma = mm->mmap;
unsigned long data = 0, stack = 0;
unsigned long exec = 0, lib = 0;
- down(&mm->mmap_sem);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
if (!vma->vm_file) {
@@ -779,7 +748,6 @@
lib += len;
}
}
- up(&mm->mmap_sem);
buffer += sprintf(buffer,
"VmSize:\t%8lu kB\n"
"VmLck:\t%8lu kB\n"
@@ -849,31 +817,15 @@
cap_t(p->cap_effective));
}
-static struct task_struct *grab_task(int pid)
-{
- struct task_struct *tsk = current;
- if (pid != tsk->pid) {
- read_lock(&tasklist_lock);
- tsk = find_task_by_pid(pid);
- if (tsk && tsk->mm && tsk->mm != &init_mm)
- mmget(tsk->mm);
- read_unlock(&tasklist_lock);
- }
- return tsk;
-}
-
-static void release_task(struct task_struct *tsk)
-{
- if (tsk != current && tsk->mm && tsk->mm != &init_mm)
- mmput(tsk->mm);
-}
static int get_status(int pid, char * buffer)
{
char * orig = buffer;
struct task_struct *tsk;
-
- tsk = grab_task(pid);
+
+ 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);
@@ -881,7 +833,6 @@
buffer = task_mem(tsk, buffer);
buffer = task_sig(tsk, buffer);
buffer = task_cap(tsk, buffer);
- release_task(tsk);
return buffer - orig;
}
@@ -893,22 +844,20 @@
int tty_pgrp;
sigset_t sigign, sigcatch;
char state;
- int res;
- tsk = grab_task(pid);
+ 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);
vsize = eip = esp = 0;
if (tsk->mm && tsk->mm != &init_mm) {
- struct vm_area_struct *vma;
-
- down(&tsk->mm->mmap_sem);
- for (vma = tsk->mm->mmap; vma; vma = vma->vm_next) {
+ struct vm_area_struct *vma = tsk->mm->mmap;
+ while (vma) {
vsize += vma->vm_end - vma->vm_start;
+ vma = vma->vm_next;
}
- up(&tsk->mm->mmap_sem);
-
eip = KSTK_EIP(tsk);
esp = KSTK_ESP(tsk);
}
@@ -929,7 +878,7 @@
nice = tsk->priority;
nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;
- res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
+ return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d\n",
pid,
@@ -974,9 +923,6 @@
tsk->nswap,
tsk->cnswap,
tsk->exit_signal);
-
- release_task(tsk);
- return res;
}
static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
@@ -1054,15 +1000,19 @@
static int get_statm(int pid, char * buffer)
{
+ struct task_struct *tsk;
int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
- struct mm_struct *mm;
- mm = get_mm_and_lock(pid);
- if (mm) {
- struct vm_area_struct * vma = mm->mmap;
+ 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) {
+ struct vm_area_struct * vma = tsk->mm->mmap;
while (vma) {
- pgd_t *pgd = pgd_offset(mm, vma->vm_start);
+ pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start);
int pages = 0, shared = 0, dirty = 0, total = 0;
statm_pgd_range(pgd, vma->vm_start, vma->vm_end, &pages, &shared, &dirty, &total);
@@ -1080,7 +1030,6 @@
drs += pages;
vma = vma->vm_next;
}
- release_mm(mm);
}
return sprintf(buffer,"%d %d %d %d %d %d %d\n",
size, resident, share, trs, lrs, drs, dt);
@@ -1118,7 +1067,7 @@
#define MAPS_LINE_MAX MAPS_LINE_MAX8
-/* FIXME: this does not do proper mm locking */
+
static ssize_t read_maps (int pid, struct file * file, char * buf,
size_t count, loff_t *ppos)
{
@@ -1250,11 +1199,15 @@
#ifdef __SMP__
static int get_pidcpu(int pid, char * buffer)
{
- struct task_struct * tsk;
+ struct task_struct * tsk = current ;
int i, len;
- tsk = grab_task(pid);
- if (!tsk)
+ 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;
len = sprintf(buffer,
@@ -1268,7 +1221,6 @@
tsk->per_cpu_utime[cpu_logical_map(i)],
tsk->per_cpu_stime[cpu_logical_map(i)]);
- release_task(tsk);
return len;
}
#endif
@@ -1306,7 +1258,7 @@
return get_meminfo(page);
#ifdef CONFIG_PCI_OLD_PROC
- case PROC_PCI:
+ case PROC_PCI:
return get_pci_list(page);
#endif
@@ -1364,11 +1316,11 @@
case PROC_CMDLINE:
return get_cmdline(page);
- case PROC_MTAB:
- return get_filesystem_info( page );
+ case PROC_MTAB:
+ return get_filesystem_info( page );
- case PROC_SWAP:
- return get_swaparea_info(page);
+ case PROC_SWAP:
+ return get_swaparea_info(page);
#ifdef CONFIG_RTC
case PROC_RTC:
return get_rtc_status(page);
@@ -1398,6 +1350,7 @@
* Grab the lock, find the task, save the uid and
* check it has an mm still (ie its not dead)
*/
+
p = find_task_by_pid(pid);
if(p)
{
@@ -1468,7 +1421,6 @@
ssize_t end;
unsigned int type, pid;
struct proc_dir_entry *dp;
- int err;
if (count > PROC_BLOCK_SIZE)
count = PROC_BLOCK_SIZE;
@@ -1497,10 +1449,8 @@
return length;
}
if (start != NULL) {
- if (length > count)
- length = count;
/* We have had block-adjusting processing! */
- err = copy_to_user(buf, start, length);
+ copy_to_user(buf, start, length);
*ppos += length;
count = length;
} else {
@@ -1512,11 +1462,11 @@
if (count + *ppos > length)
count = length - *ppos;
end = count + *ppos;
- err = copy_to_user(buf, (char *) page + *ppos, count);
+ copy_to_user(buf, (char *) page + *ppos, count);
*ppos = end;
}
free_page(page);
- return err ? -EFAULT : count;
+ return count;
}
static struct file_operations proc_array_operations = {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)