diff -urN linux/fs/proc/array.c linux-2.2.3-proc_tasklock/fs/proc/array.c
--- linux/fs/proc/array.c	Sat Mar 13 11:57:16 1999
+++ linux-2.2.3-proc_tasklock/fs/proc/array.c	Sat Mar 13 23:14:27 1999
@@ -454,26 +454,31 @@
 static int get_env(int pid, char * buffer)
 {
 	struct task_struct *p;
+	int len = 0;
 	
 	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->env_start, p->mm->env_end, buffer);
+		goto out;
+	len = get_array(p, p->mm->env_start, p->mm->env_end, buffer);
+out:
+	read_unlock(&tasklist_lock);
+	return len;
 }
 
 static int get_arg(int pid, char * buffer)
 {
 	struct task_struct *p;
+	int len = 0;
 
 	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);
+		goto out;
+	len = get_array(p, p->mm->arg_start, p->mm->arg_end, buffer);
+out:
+	read_unlock(&tasklist_lock);
+	return len;
 }
 
 /*
@@ -825,14 +830,15 @@
 
 	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;
+		goto out;
 	buffer = task_name(tsk, buffer);
 	buffer = task_state(tsk, buffer);
 	buffer = task_mem(tsk, buffer);
 	buffer = task_sig(tsk, buffer);
 	buffer = task_cap(tsk, buffer);
+out:
+	read_unlock(&tasklist_lock);
 	return buffer - orig;
 }
 
@@ -841,15 +847,14 @@
 	struct task_struct *tsk;
 	unsigned long vsize, eip, esp, wchan;
 	long priority, nice;
-	int tty_pgrp;
+	int tty_pgrp, len = 0;
 	sigset_t sigign, sigcatch;
 	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;
+		goto out;
 	state = *get_task_state(tsk);
 	vsize = eip = esp = 0;
 	if (tsk->mm && tsk->mm != &init_mm) {
@@ -878,7 +883,7 @@
 	nice = tsk->priority;
 	nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;
 
-	return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
+	len = 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,
@@ -923,6 +928,9 @@
 		tsk->nswap,
 		tsk->cnswap,
 		tsk->exit_signal);
+out:
+	read_unlock(&tasklist_lock);
+	return len;
 }
 		
 static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
@@ -1001,13 +1009,12 @@
 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;
+	int len=0, 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;
+		goto out;
 	if (tsk->mm && tsk->mm != &init_mm) {
 		struct vm_area_struct * vma = tsk->mm->mmap;
 
@@ -1031,8 +1038,11 @@
 			vma = vma->vm_next;
 		}
 	}
-	return sprintf(buffer,"%d %d %d %d %d %d %d\n",
+	len = sprintf(buffer,"%d %d %d %d %d %d %d\n",
 		       size, resident, share, trs, lrs, drs, dt);
+out:
+	read_unlock(&tasklist_lock);
+	return len;
 }
 
 /*
@@ -1200,15 +1210,13 @@
 static int get_pidcpu(int pid, char * buffer)
 {
 	struct task_struct * tsk = current ;
-	int i, len;
+	int i, len = 0;
 
 	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;
+		goto out;
 
 	len = sprintf(buffer,
 		"cpu  %lu %lu\n",
@@ -1220,7 +1228,8 @@
 			i,
 			tsk->per_cpu_utime[cpu_logical_map(i)],
 			tsk->per_cpu_stime[cpu_logical_map(i)]);
-
+out:
+	read_unlock(&tasklist_lock);
 	return len;
 }
 #endif
