summaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/Makefile6
-rw-r--r--fs/proc/array.c89
-rw-r--r--fs/proc/base.c13
-rw-r--r--fs/proc/fd.c13
-rw-r--r--fs/proc/generic.c28
-rw-r--r--fs/proc/inode-alloc.txt50
-rw-r--r--fs/proc/inode.c5
-rw-r--r--fs/proc/link.c5
-rw-r--r--fs/proc/net.c2
-rw-r--r--fs/proc/proc_tty.c5
-rw-r--r--fs/proc/procfs_syms.c4
-rw-r--r--fs/proc/root.c121
12 files changed, 228 insertions, 113 deletions
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index d01072a4b..cd488e328 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -1,11 +1,11 @@
#
-# Makefile for the linux proc-filesystem routines.
+# Makefile for the Linux proc filesystem routines.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
+# unless it's something special (not a .c file).
#
-# Note 2! The CFLAGS definitions are now in the main makefile...
+# Note 2! The CFLAGS definitions are now in the main makefile.
O_TARGET := proc.o
O_OBJS := inode.o root.o base.o generic.o mem.o link.o fd.o array.o \
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 7376c30f5..cde538846 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -29,12 +29,14 @@
* Yves Arrouye : remove removal of trailing spaces in get_array.
* <Yves.Arrouye@marin.fdn.fr>
- * Jerome Forissier : added per-cpu time information to /proc/stat
+ * Jerome Forissier : added per-CPU time information to /proc/stat
* and /proc/<pid>/cpu extension
* <forissier@isia.cma.fr>
* - Incorporation and non-SMP safe operation
* of forissier patch in 2.1.78 by
* Hans Marcus <crowbar@concepts.nl>
+ *
+ * aeb@cwi.nl : /proc/partitions
*/
#include <linux/types.h>
@@ -559,6 +561,23 @@ static unsigned long get_wchan(struct task_struct *p)
}
#elif defined(__powerpc__)
return (p->tss.wchan);
+#elif defined (CONFIG_ARM)
+ {
+ unsigned long fp, lr;
+ unsigned long stack_page;
+ int count = 0;
+
+ stack_page = 4096 + (unsigned long)p;
+ fp = get_css_fp (&p->tss);
+ do {
+ if (fp < stack_page || fp > 4092+stack_page)
+ return 0;
+ lr = pc_pointer (((unsigned long *)fp)[-1]);
+ if (lr < first_sched || lr > last_sched)
+ return lr;
+ fp = *(unsigned long *) (fp - 12);
+ } while (count ++ < 16);
+ }
#endif
return 0;
@@ -576,6 +595,9 @@ static unsigned long get_wchan(struct task_struct *p)
# define KSTK_EIP(tsk) \
(*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk)))
# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
+#elif defined(CONFIG_ARM)
+# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
+# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
#elif defined(__mc68000__)
#define KSTK_EIP(tsk) \
({ \
@@ -729,21 +751,6 @@ static inline char * task_mem(struct task_struct *p, char *buffer)
return buffer;
}
-char * render_sigset_t(sigset_t *set, char *buffer)
-{
- int i = _NSIG, x;
- do {
- i -= 4, x = 0;
- if (sigismember(set, i+1)) x |= 1;
- if (sigismember(set, i+2)) x |= 2;
- if (sigismember(set, i+3)) x |= 4;
- if (sigismember(set, i+4)) x |= 8;
- *buffer++ = (x < 10 ? '0' : 'a' - 10) + x;
- } while (i >= 4);
- *buffer = 0;
- return buffer;
-}
-
static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
sigset_t *catch)
{
@@ -779,7 +786,7 @@ static inline char * task_sig(struct task_struct *p, char *buffer)
buffer += sprintf(buffer, "SigIgn:\t");
buffer = render_sigset_t(&ign, buffer);
*buffer++ = '\n';
- buffer += sprintf(buffer, "SigCat:\t");
+ buffer += sprintf(buffer, "SigCgt:\t"); /* Linux 2.0 uses "SigCgt" */
buffer = render_sigset_t(&catch, buffer);
*buffer++ = '\n';
@@ -822,10 +829,6 @@ static int get_stat(int pid, char * buffer)
long priority, nice;
int tty_pgrp;
sigset_t sigign, sigcatch;
- char signal_str[sizeof(sigset_t)*2+1];
- char blocked_str[sizeof(sigset_t)*2+1];
- char sigign_str[sizeof(sigset_t)*2+1];
- char sigcatch_str[sizeof(sigset_t)*2+1];
char state;
read_lock(&tasklist_lock);
@@ -848,10 +851,6 @@ static int get_stat(int pid, char * buffer)
wchan = get_wchan(tsk);
collect_sigign_sigcatch(tsk, &sigign, &sigcatch);
- render_sigset_t(&tsk->signal, signal_str);
- render_sigset_t(&tsk->blocked, blocked_str);
- render_sigset_t(&sigign, sigign_str);
- render_sigset_t(&sigcatch, sigcatch_str);
if (tsk->tty)
tty_pgrp = tsk->tty->pgrp;
@@ -859,7 +858,7 @@ static int get_stat(int pid, char * buffer)
tty_pgrp = -1;
/* scale priority and nice values from timeslices to -20..20 */
- /* to make it look like a "normal" unix priority/nice value */
+ /* to make it look like a "normal" Unix priority/nice value */
priority = tsk->counter;
priority = 20 - (priority * 10 + DEF_PRIORITY / 2) / DEF_PRIORITY;
nice = tsk->priority;
@@ -867,7 +866,7 @@ static int get_stat(int pid, char * buffer)
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 %s %s %s %s %lu %lu %lu\n",
+%lu %lu %lu %lu %lu %lu %lu %lu\n",
pid,
tsk->comm,
state,
@@ -898,10 +897,14 @@ static int get_stat(int pid, char * buffer)
tsk->mm ? tsk->mm->start_stack : 0,
esp,
eip,
- signal_str,
- blocked_str,
- sigign_str,
- sigcatch_str,
+ /* The signal information here is obsolete.
+ * It must be decimal for Linux 2.0 compatibility.
+ * Use /proc/#/status for real-time signals.
+ */
+ tsk->signal .sig[0] & 0x7fffffffUL,
+ tsk->blocked.sig[0] & 0x7fffffffUL,
+ sigign .sig[0] & 0x7fffffffUL,
+ sigcatch .sig[0] & 0x7fffffffUL,
wchan,
tsk->nswap,
tsk->cnswap);
@@ -982,7 +985,7 @@ static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long en
static int get_statm(int pid, char * buffer)
{
- struct task_struct *tsk = find_task_by_pid(pid);
+ struct task_struct *tsk;
int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
read_lock(&tasklist_lock);
@@ -1080,7 +1083,7 @@ static ssize_t read_maps (int pid, struct file * file, char * buf,
goto getlen_out;
/* Check whether the mmaps could change if we sleep */
- volatile_task = (p != current || p->mm->count > 1);
+ volatile_task = (p != current || atomic_read(&p->mm->count) > 1);
/* decode f_pos */
lineno = *ppos >> MAPS_LINE_SHIFT;
@@ -1212,6 +1215,7 @@ extern int get_module_list(char *);
extern int get_ksyms_list(char *, char **, off_t, int);
#endif
extern int get_device_list(char *);
+extern int get_partition_list(char *);
extern int get_filesystem_list(char *);
extern int get_filesystem_info( char * );
extern int get_irq_list(char *);
@@ -1222,12 +1226,8 @@ extern int get_md_status (char *);
extern int get_rtc_status (char *);
extern int get_locks_status (char *, char **, off_t, int);
extern int get_swaparea_info (char *);
-#ifdef CONFIG_ZORRO
-extern int zorro_get_list(char *);
-#endif
-#if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI)
extern int get_hardware_list(char *);
-#endif
+extern int get_stram_list(char *);
static long get_root_array(char * page, int type, char **start,
off_t offset, unsigned long length)
@@ -1275,6 +1275,9 @@ static long get_root_array(char * page, int type, char **start,
case PROC_DEVICES:
return get_device_list(page);
+ case PROC_PARTITIONS:
+ return get_partition_list(page);
+
case PROC_INTERRUPTS:
return get_irq_list(page);
@@ -1308,14 +1311,14 @@ static long get_root_array(char * page, int type, char **start,
#endif
case PROC_LOCKS:
return get_locks_status(page, start, offset, length);
-#ifdef CONFIG_ZORRO
- case PROC_ZORRO:
- return zorro_get_list(page);
-#endif
-#if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI)
+#ifdef CONFIG_PROC_HARDWARE
case PROC_HARDWARE:
return get_hardware_list(page);
#endif
+#ifdef CONFIG_STRAM_PROC
+ case PROC_STRAM:
+ return get_stram_list(page);
+#endif
}
return -EBADF;
}
diff --git a/fs/proc/base.c b/fs/proc/base.c
index e535276bb..edfe8b758 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/init.h>
static struct file_operations proc_base_operations = {
NULL, /* lseek - default */
@@ -62,10 +63,14 @@ static void proc_pid_fill_inode(struct inode * inode, int fill)
read_lock(&tasklist_lock);
if (fill && (p = find_task_by_pid(pid)) != NULL) {
+ uid_t uid = 0;
+ gid_t gid = 0;
if (p->dumpable || ino == PROC_PID_INO) {
- inode->i_uid = p->euid;
- inode->i_gid = p->gid;
+ uid = p->euid;
+ gid = p->egid;
}
+ inode->i_uid = uid;
+ inode->i_gid = gid;
}
read_unlock(&tasklist_lock);
}
@@ -116,7 +121,7 @@ static struct proc_dir_entry proc_pid_exe = {
};
static struct proc_dir_entry proc_pid_fd = {
PROC_PID_FD, 2, "fd",
- S_IFDIR | S_IRUSR | S_IXUSR, 1, 0, 0,
+ S_IFDIR | S_IRUSR | S_IXUSR, 2, 0, 0,
0, &proc_fd_inode_operations,
NULL, proc_pid_fill_inode,
};
@@ -169,7 +174,7 @@ static struct proc_dir_entry proc_pid_cpu = {
};
#endif
-void proc_base_init(void)
+__initfunc(void proc_base_init(void))
{
#if CONFIG_AP1000
proc_register(&proc_pid, &proc_pid_ringbuf);
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 04da4f412..57f99bfd7 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -4,6 +4,10 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*
* proc fd directory handling functions
+ *
+ * 01-May-98 Edgar Toernig <froese@gmx.de>
+ * Added support for more than 256 fds.
+ * Limit raised to 32768.
*/
#include <linux/errno.h>
@@ -91,7 +95,7 @@ static int proc_lookupfd(struct inode * dir, struct dentry * dentry)
goto out;
fd *= 10;
fd += c;
- if (fd & 0xffff0000)
+ if (fd & 0xffff8000)
goto out;
}
@@ -111,8 +115,7 @@ static int proc_lookupfd(struct inode * dir, struct dentry * dentry)
if (!file || !file->f_dentry)
goto out;
- /* N.B. What happens if fd > 255?? */
- ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
+ ino = (pid << 16) + PROC_PID_FD_DIR + fd;
inode = proc_get_inode(dir->i_sb, ino, NULL);
if (inode) {
d_add(dentry, inode);
@@ -144,7 +147,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
goto out;
for (fd = filp->f_pos; fd < 2; fd++, filp->f_pos++) {
- unsigned long ino = inode->i_ino;
+ ino = inode->i_ino;
if (fd)
ino = (ino & 0xffff0000) | PROC_PID_INO;
if (filldir(dirent, "..", fd+1, fd, ino) < 0)
@@ -176,7 +179,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
/* Drop the task lock, as the filldir function may block */
read_unlock(&tasklist_lock);
- ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
+ ino = (pid << 16) + PROC_PID_FD_DIR + fd;
if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
goto out;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index a38481c85..a9b00f1f5 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -154,14 +154,19 @@ proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
break;
}
- n -= copy_to_user(buf, start, n); /* BUG ??? */
+ /* This is a hack to allow mangling of file pos independent
+ * of actual bytes read. Simply place the data at page,
+ * return the bytes, and set `start' to the desired offset
+ * as an unsigned int. - Paul.Russell@rustcorp.com.au
+ */
+ n -= copy_to_user(buf, start < page ? page : start, n);
if (n == 0) {
if (retval == 0)
retval = -EFAULT;
break;
}
-
- *ppos += n; /* Move down the file */
+
+ *ppos += start < page ? (long)start : n; /* Move down the file */
nbytes -= n;
buf += n;
retval += n;
@@ -255,13 +260,16 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
ent->name = ((char *) ent) + sizeof(*ent);
ent->namelen = len;
- if (mode == S_IFDIR) {
+ if (S_ISDIR(mode)) {
+ if ((mode & S_IALLUGO) == 0)
mode |= S_IRUGO | S_IXUGO;
ent->ops = &proc_dyna_dir_inode_operations;
ent->nlink = 2;
- }
- else if (mode == 0) {
- mode = S_IFREG | S_IRUGO;
+ } else {
+ if ((mode & S_IFMT) == 0)
+ mode |= S_IFREG;
+ if ((mode & S_IALLUGO) == 0)
+ mode |= S_IRUGO;
ent->nlink = 1;
}
ent->mode = mode;
@@ -275,7 +283,11 @@ out:
extern void free_proc_entry(struct proc_dir_entry *);
void free_proc_entry(struct proc_dir_entry *de)
{
- kfree(de);
+ int ino = de->low_ino;
+
+ if (ino >= PROC_DYNAMIC_FIRST &&
+ ino < PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
+ kfree(de);
}
/*
diff --git a/fs/proc/inode-alloc.txt b/fs/proc/inode-alloc.txt
new file mode 100644
index 000000000..440d3baf8
--- /dev/null
+++ b/fs/proc/inode-alloc.txt
@@ -0,0 +1,50 @@
+Inode allocations in the proc-fs (hex-numbers):
+
+ 00000000 reserved
+ 00000001-00000fff static entries
+ 001 root-ino
+ 002 load-avg
+ 003 uptime
+ ...
+ 080 net/*
+ ...
+ 100 scsi/*
+ ...
+ xxx mca/*
+ ...
+ yyy bus/*
+ ...
+ fff end
+
+ 00001000-00001fff dynamic entries
+
+ 00002000-00002fff openprom entries
+
+ 0001xxxx-7fffxxxx pid-dir entries for pid 1-7fff
+ 0000 unused
+ 0001 unused
+ 0002 pid
+ 0003 pid/status
+ ...
+ 0008 pid/fd
+ ...
+ 00xx-00ff unused
+ 01xx pid/fd/* for fd 0-ff
+ ...
+ 01ff end
+ 0200-ffff unused
+
+ 80000000-ffffffff unused
+
+
+
+New allocation:
+
+ 00000000-0000ffff unchanged
+
+ 0001xxxx-7fffxxxx pid-dir entries for pid 1-7fff
+ 0000-00ff unchanged
+ 0100-7fff unused
+ 8000-ffff pid/fd/* for fd 0-7fff
+
+ 80000000-ffffffff unchanged
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index b4ca1094c..44c4916f8 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -382,10 +382,9 @@ void proc_read_inode(struct inode * inode)
inode->i_uid = p->euid;
inode->i_gid = p->egid;
}
- switch (ino >> 8) {
+ if (ino & PROC_PID_FD_DIR) {
struct file * file;
- case PROC_PID_FD_DIR:
- ino &= 0xff;
+ ino &= 0x7fff;
file = fcheck_task(p, ino);
if (!file)
goto out_unlock;
diff --git a/fs/proc/link.c b/fs/proc/link.c
index 28bb81a93..05ab85030 100644
--- a/fs/proc/link.c
+++ b/fs/proc/link.c
@@ -111,10 +111,9 @@ static struct dentry * proc_follow_link(struct dentry *dentry,
goto out_unlock;
}
default:
- switch (ino >> 8) {
+ if (ino & PROC_PID_FD_DIR) {
struct file * file;
- case PROC_PID_FD_DIR:
- ino &= 0xff;
+ ino &= 0x7fff;
file = fcheck_task(p, ino);
if (!file || !file->f_dentry)
goto out_unlock;
diff --git a/fs/proc/net.c b/fs/proc/net.c
index 257487569..408c8e0d4 100644
--- a/fs/proc/net.c
+++ b/fs/proc/net.c
@@ -20,7 +20,7 @@
* Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
* /proc/net/snmp.
* Alan Cox (gw4pts@gw4pts.ampr.org) 1/95
- * Added Appletalk slots
+ * Added AppleTalk slots
*
* proc net directory handling functions
*/
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
index 9523ff9f0..5ba245615 100644
--- a/fs/proc/proc_tty.c
+++ b/fs/proc/proc_tty.c
@@ -6,6 +6,7 @@
#include <asm/uaccess.h>
+#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
@@ -79,7 +80,7 @@ static int tty_drivers_read_proc(char *page, char **start, off_t off,
break;
}
len += sprintf(page+len, "%-20s /dev/%-8s %3d %7s %s\n",
- p->driver_name ? p->driver_name : "",
+ p->driver_name ? p->driver_name : "unknown",
p->name, p->major, range, type);
if (len+begin > off+count)
break;
@@ -169,7 +170,7 @@ void proc_tty_unregister_driver(struct tty_driver *driver)
/*
* Called by proc_root_init() to initialize the /proc/tty subtree
*/
-void proc_tty_init(void)
+__initfunc(void proc_tty_init(void))
{
struct proc_dir_entry *ent;
diff --git a/fs/proc/procfs_syms.c b/fs/proc/procfs_syms.c
index d3077ea79..6a6ef687e 100644
--- a/fs/proc/procfs_syms.c
+++ b/fs/proc/procfs_syms.c
@@ -11,17 +11,21 @@
extern int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start,
off_t offset, int length, int inout);
extern struct inode_operations proc_scsi_inode_operations;
+extern struct proc_dir_entry proc_sys_root;
+EXPORT_SYMBOL(proc_sys_root);
EXPORT_SYMBOL(proc_register);
EXPORT_SYMBOL(proc_unregister);
EXPORT_SYMBOL(create_proc_entry);
EXPORT_SYMBOL(remove_proc_entry);
EXPORT_SYMBOL(proc_root);
+EXPORT_SYMBOL(proc_root_fs);
EXPORT_SYMBOL(proc_get_inode);
EXPORT_SYMBOL(in_group_p);
EXPORT_SYMBOL(proc_dir_inode_operations);
EXPORT_SYMBOL(proc_net_inode_operations);
EXPORT_SYMBOL(proc_net);
+EXPORT_SYMBOL(proc_bus);
/*
* This is required so that if we load scsi later, that the
diff --git a/fs/proc/root.c b/fs/proc/root.c
index afc440fc0..999783ee5 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -13,10 +13,14 @@
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/config.h>
+#include <linux/init.h>
#include <asm/bitops.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
+#ifdef CONFIG_ZORRO
+#include <linux/zorro.h>
+#endif
/*
* Offset of the first process in the /proc root directory..
@@ -498,25 +502,25 @@ static struct proc_dir_entry proc_root_version = {
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations
};
-#ifdef CONFIG_ZORRO
-static struct proc_dir_entry proc_root_zorro = {
- PROC_ZORRO, 5, "zorro",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_array_inode_operations
-};
-#endif
static struct proc_dir_entry proc_root_cpuinfo = {
PROC_CPUINFO, 7, "cpuinfo",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations
};
-#if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI)
+#if defined (CONFIG_PROC_HARDWARE)
static struct proc_dir_entry proc_root_hardware = {
PROC_HARDWARE, 8, "hardware",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations
};
#endif
+#ifdef CONFIG_STRAM_PROC
+static struct proc_dir_entry proc_root_stram = {
+ PROC_STRAM, 5, "stram",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
+};
+#endif
static struct proc_dir_entry proc_root_self = {
PROC_SELF, 4, "self",
S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0,
@@ -556,6 +560,11 @@ static struct proc_dir_entry proc_root_devices = {
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations
};
+static struct proc_dir_entry proc_root_partitions = {
+ PROC_PARTITIONS, 10, "partitions",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
+};
static struct proc_dir_entry proc_root_interrupts = {
PROC_INTERRUPTS, 10,"interrupts",
S_IFREG | S_IRUGO, 1, 0, 0,
@@ -566,6 +575,14 @@ static struct proc_dir_entry proc_root_filesystems = {
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_array_inode_operations
};
+struct proc_dir_entry proc_root_fs = {
+ PROC_FS, 2, "fs",
+ S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+ 0, &proc_dir_inode_operations,
+ NULL, NULL,
+ NULL,
+ NULL, NULL
+};
static struct proc_dir_entry proc_root_dma = {
PROC_DMA, 3, "dma",
S_IFREG | S_IRUGO, 1, 0, 0,
@@ -631,7 +648,7 @@ static struct proc_dir_entry proc_root_ppc_htab = {
};
#endif
-void proc_root_init(void)
+__initfunc(void proc_root_init(void))
{
proc_base_init();
proc_register(&proc_root, &proc_root_loadavg);
@@ -639,9 +656,6 @@ void proc_root_init(void)
proc_register(&proc_root, &proc_root_meminfo);
proc_register(&proc_root, &proc_root_kmsg);
proc_register(&proc_root, &proc_root_version);
-#ifdef CONFIG_ZORRO
- proc_register(&proc_root, &proc_root_zorro);
-#endif
proc_register(&proc_root, &proc_root_cpuinfo);
proc_register(&proc_root, &proc_root_self);
proc_net = create_proc_entry("net", S_IFDIR, 0);
@@ -665,8 +679,10 @@ void proc_root_init(void)
#endif
proc_register(&proc_root, &proc_root_stat);
proc_register(&proc_root, &proc_root_devices);
+ proc_register(&proc_root, &proc_root_partitions);
proc_register(&proc_root, &proc_root_interrupts);
proc_register(&proc_root, &proc_root_filesystems);
+ proc_register(&proc_root, &proc_root_fs);
proc_register(&proc_root, &proc_root_dma);
proc_register(&proc_root, &proc_root_ioports);
proc_register(&proc_root, &proc_root_cmdline);
@@ -687,14 +703,17 @@ void proc_root_init(void)
#endif
proc_register(&proc_root, &proc_openprom);
#endif
-#if defined (CONFIG_AMIGA) || defined (CONFIG_ATARI)
+#ifdef CONFIG_PROC_HARDWARE
proc_register(&proc_root, &proc_root_hardware);
#endif
+#ifdef CONFIG_STRAM_PROC
+ proc_register(&proc_root, &proc_root_stram);
+#endif
proc_register(&proc_root, &proc_root_slab);
if (prof_shift) {
proc_register(&proc_root, &proc_root_profile);
- proc_root_profile.size = (1+prof_len) * sizeof(unsigned long);
+ proc_root_profile.size = (1+prof_len) * sizeof(unsigned int);
}
proc_tty_init();
@@ -810,16 +829,14 @@ static int proc_root_lookup(struct inode * dir, struct dentry * dentry)
}
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock);
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) {
- read_unlock(&tasklist_lock);
+ if (!inode)
return -EINVAL;
- }
}
- read_unlock(&tasklist_lock);
dentry->d_op = &proc_dentry_operations;
d_add(dentry, inode);
@@ -886,46 +903,68 @@ int proc_readdir(struct file * filp,
return 1;
}
-#define NUMBUF 10
+#define PROC_NUMBUF 10
+#define PROC_MAXPIDS 20
+
+/*
+ * Get a few pid's to return for filldir - we need to hold the
+ * tasklist lock while doing this, and we must release it before
+ * we actually do the filldir itself, so we use a temp buffer..
+ */
+static int get_pid_list(unsigned int index, unsigned int *pids)
+{
+ struct task_struct *p;
+ int nr = FIRST_PROCESS_ENTRY;
+ int nr_pids = 0;
+
+ read_lock(&tasklist_lock);
+ for_each_task(p) {
+ int pid;
+ if (nr++ < index)
+ continue;
+ pid = p->pid;
+ if (!pid)
+ continue;
+ pids[nr_pids] = pid;
+ nr_pids++;
+ if (nr_pids >= PROC_MAXPIDS)
+ break;
+ }
+ read_unlock(&tasklist_lock);
+ return nr_pids;
+}
static int proc_root_readdir(struct file * filp,
void * dirent, filldir_t filldir)
{
- struct task_struct *p;
- char buf[NUMBUF];
+ unsigned int pid_array[PROC_MAXPIDS];
+ char buf[PROC_NUMBUF];
unsigned int nr = filp->f_pos;
+ unsigned int nr_pids, i;
if (nr < FIRST_PROCESS_ENTRY) {
int error = proc_readdir(filp, dirent, filldir);
if (error <= 0)
return error;
- filp->f_pos = FIRST_PROCESS_ENTRY;
+ filp->f_pos = nr = FIRST_PROCESS_ENTRY;
}
- nr = FIRST_PROCESS_ENTRY;
- read_lock(&tasklist_lock);
- for_each_task(p) {
- unsigned int pid;
+ nr_pids = get_pid_list(nr, pid_array);
- if(nr++ < filp->f_pos)
- continue;
+ for (i = 0; i < nr_pids; i++) {
+ int pid = pid_array[i];
+ unsigned long j = PROC_NUMBUF;
- if((pid = p->pid) != 0) {
- unsigned long j = NUMBUF, i = pid;
+ do {
+ j--;
+ buf[j] = '0' + (pid % 10);
+ pid /= 10;
+ } while (pid);
- do {
- j--;
- buf[j] = '0' + (i % 10);
- i /= 10;
- } while (i);
-
- if (filldir(dirent, buf+j, NUMBUF-j,
- filp->f_pos, (pid << 16) + PROC_PID_INO) < 0)
- break;
- }
+ if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, (pid << 16) + PROC_PID_INO) < 0)
+ break;
filp->f_pos++;
}
- read_unlock(&tasklist_lock);
return 0;
}