summaryrefslogtreecommitdiffstats
path: root/fs/proc/root.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
committer <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
commit19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch)
tree40b1cb534496a7f1ca0f5c314a523c69f1fee464 /fs/proc/root.c
parent7206675c40394c78a90e74812bbdbf8cf3cca1be (diff)
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'fs/proc/root.c')
-rw-r--r--fs/proc/root.c298
1 files changed, 253 insertions, 45 deletions
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 70150f587..e5bb9d51b 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -14,6 +14,9 @@
#include <linux/stat.h>
#include <linux/config.h>
#include <asm/bitops.h>
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
/*
* Offset of the first process in the /proc root directory..
@@ -38,7 +41,7 @@ static struct file_operations proc_dir_operations = {
NULL, /* read - bad */
NULL, /* write - bad */
proc_readdir, /* readdir */
- NULL, /* select - default */
+ NULL, /* poll - default */
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
@@ -79,7 +82,7 @@ static struct file_operations proc_root_operations = {
NULL, /* read - bad */
NULL, /* write - bad */
proc_root_readdir, /* readdir */
- NULL, /* select - default */
+ NULL, /* poll - default */
NULL, /* ioctl - default */
NULL, /* mmap */
NULL, /* no special open code */
@@ -122,23 +125,19 @@ struct proc_dir_entry proc_root = {
&proc_root, NULL
};
-struct proc_dir_entry proc_net = {
- PROC_NET, 3, "net",
- S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
- 0, &proc_dir_inode_operations,
- NULL, NULL,
- NULL,
- NULL, NULL
-};
+struct proc_dir_entry *proc_net, *proc_scsi;
-struct proc_dir_entry proc_scsi = {
- PROC_SCSI, 4, "scsi",
+#ifdef CONFIG_MCA
+struct proc_dir_entry proc_mca = {
+ PROC_MCA, 3, "mca",
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
0, &proc_dir_inode_operations,
NULL, NULL,
NULL, &proc_root, NULL
};
+#endif
+#ifdef CONFIG_SYSCTL
struct proc_dir_entry proc_sys_root = {
PROC_SYS, 3, "sys", /* inode, name */
S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, /* mode, nlink, uid, gid */
@@ -147,14 +146,181 @@ struct proc_dir_entry proc_sys_root = {
NULL, /* next */
NULL, NULL /* parent, subdir */
};
+#endif
+
+#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
+
+static int (*proc_openprom_defreaddir_ptr)(struct inode *, struct file *, void *, filldir_t);
+static int (*proc_openprom_deflookup_ptr)(struct inode *, const char *, int, struct inode **);
+void (*proc_openprom_use)(struct inode *, int) = 0;
+static struct openpromfs_dev *proc_openprom_devices = NULL;
+static ino_t proc_openpromdev_ino = PROC_OPENPROMD_FIRST;
+
+struct inode_operations *
+proc_openprom_register(int (*readdir)(struct inode *, struct file *, void *, filldir_t),
+ int (*lookup)(struct inode *, const char *, int, struct inode **),
+ void (*use)(struct inode *, int),
+ struct openpromfs_dev ***devices)
+{
+ proc_openprom_defreaddir_ptr = (proc_openprom_inode_operations.default_file_ops)->readdir;
+ proc_openprom_deflookup_ptr = proc_openprom_inode_operations.lookup;
+ (proc_openprom_inode_operations.default_file_ops)->readdir = readdir;
+ proc_openprom_inode_operations.lookup = lookup;
+ proc_openprom_use = use;
+ *devices = &proc_openprom_devices;
+ return &proc_openprom_inode_operations;
+}
+
+int proc_openprom_regdev(struct openpromfs_dev *d)
+{
+ if (proc_openpromdev_ino == PROC_OPENPROMD_FIRST + PROC_NOPENPROMD) return -1;
+ d->next = proc_openprom_devices;
+ d->inode = proc_openpromdev_ino++;
+ proc_openprom_devices = d;
+ return 0;
+}
+
+int proc_openprom_unregdev(struct openpromfs_dev *d)
+{
+ if (d == proc_openprom_devices) {
+ proc_openprom_devices = d->next;
+ } else if (!proc_openprom_devices)
+ return -1;
+ else {
+ struct openpromfs_dev *p;
+
+ for (p = proc_openprom_devices; p->next != d && p->next; p = p->next);
+ if (!p->next) return -1;
+ p->next = d->next;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_SUN_OPENPROMFS_MODULE
+void
+proc_openprom_deregister(void)
+{
+ (proc_openprom_inode_operations.default_file_ops)->readdir = proc_openprom_defreaddir_ptr;
+ proc_openprom_inode_operations.lookup = proc_openprom_deflookup_ptr;
+ proc_openprom_use = 0;
+}
+#endif
+
+#if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KERNELD)
+static int
+proc_openprom_defreaddir(struct inode * inode, struct file * filp,
+ void * dirent, filldir_t filldir)
+{
+ request_module("openpromfs");
+ if ((proc_openprom_inode_operations.default_file_ops)->readdir !=
+ proc_openprom_defreaddir)
+ return (proc_openprom_inode_operations.default_file_ops)->readdir
+ (inode, filp, dirent, filldir);
+ return -EINVAL;
+}
+
+static int
+proc_openprom_deflookup(struct inode * dir,const char * name, int len,
+ struct inode ** result)
+{
+ request_module("openpromfs");
+ if (proc_openprom_inode_operations.lookup !=
+ proc_openprom_deflookup)
+ return proc_openprom_inode_operations.lookup
+ (dir, name, len, result);
+ iput(dir);
+ return -ENOENT;
+}
+#endif
+
+static struct file_operations proc_openprom_operations = {
+ NULL, /* lseek - default */
+ NULL, /* read - bad */
+ NULL, /* write - bad */
+#if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KERNELD)
+ proc_openprom_defreaddir,/* readdir */
+#else
+ NULL, /* readdir */
+#endif
+ NULL, /* poll - default */
+ NULL, /* ioctl - default */
+ NULL, /* mmap */
+ NULL, /* no special open code */
+ NULL, /* no special release code */
+ NULL /* can't fsync */
+};
+
+struct inode_operations proc_openprom_inode_operations = {
+ &proc_openprom_operations,/* default net directory file-ops */
+ NULL, /* create */
+#if defined(CONFIG_SUN_OPENPROMFS_MODULE) && defined(CONFIG_KERNELD)
+ proc_openprom_deflookup,/* lookup */
+#else
+ NULL, /* lookup */
+#endif
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
+ NULL, /* bmap */
+ NULL, /* truncate */
+ NULL /* permission */
+};
+
+struct proc_dir_entry proc_openprom = {
+ PROC_OPENPROM, 8, "openprom",
+ S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+ 0, &proc_openprom_inode_operations,
+ NULL, NULL,
+ NULL,
+ &proc_root, NULL
+};
+
+extern void openpromfs_init (void);
+#endif /* CONFIG_SUN_OPENPROMFS */
+
+static int make_inode_number(void)
+{
+ int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
+ if (i<0 || i>=PROC_NDYNAMIC)
+ return -1;
+ set_bit(i, (void *) proc_alloc_map);
+ return PROC_DYNAMIC_FIRST + i;
+}
int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
+ int i;
+
+ if (dp->low_ino == 0) {
+ i = make_inode_number();
+ if (i < 0)
+ return -EAGAIN;
+ dp->low_ino = i;
+ }
dp->next = dir->subdir;
dp->parent = dir;
dir->subdir = dp;
- if (S_ISDIR(dp->mode))
+ if (S_ISDIR(dp->mode)) {
+ if (dp->ops == NULL)
+ dp->ops = &proc_dir_inode_operations;
dir->nlink++;
+ } else {
+ if (dp->ops == NULL)
+ dp->ops = &proc_file_inode_operations;
+ }
+ /*
+ * kludge until we fixup the md device driver
+ */
+ if (dp->low_ino == PROC_MD)
+ dp->ops = &proc_array_inode_operations;
return 0;
}
@@ -179,30 +345,6 @@ int proc_unregister(struct proc_dir_entry * dir, int ino)
return -EINVAL;
}
-static int make_inode_number(void)
-{
- int i = find_first_zero_bit((void *) proc_alloc_map, PROC_NDYNAMIC);
- if (i<0 || i>=PROC_NDYNAMIC)
- return -1;
- set_bit(i, (void *) proc_alloc_map);
- return PROC_DYNAMIC_FIRST + i;
-}
-
-int proc_register_dynamic(struct proc_dir_entry * dir,
- struct proc_dir_entry * dp)
-{
- int i = make_inode_number();
- if (i < 0)
- return -EAGAIN;
- dp->low_ino = i;
- dp->next = dir->subdir;
- dp->parent = dir;
- dir->subdir = dp;
- if (S_ISDIR(dp->mode))
- dir->nlink++;
- return 0;
-}
-
/*
* /proc/self:
*/
@@ -223,7 +365,7 @@ static int proc_self_readlink(struct inode * inode, char * buffer, int buflen)
char tmp[30];
iput(inode);
- len = 1 + sprintf(tmp, "%d", current->pid);
+ len = sprintf(tmp, "%d", current->pid);
if (buflen < len)
len = buflen;
copy_to_user(buffer, tmp, len);
@@ -253,32 +395,46 @@ static struct inode_operations proc_self_inode_operations = {
static struct proc_dir_entry proc_root_loadavg = {
PROC_LOADAVG, 7, "loadavg",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_uptime = {
PROC_UPTIME, 6, "uptime",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_meminfo = {
PROC_MEMINFO, 7, "meminfo",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_kmsg = {
PROC_KMSG, 4, "kmsg",
S_IFREG | S_IRUSR, 1, 0, 0,
+ 0, &proc_kmsg_inode_operations
};
static struct proc_dir_entry proc_root_version = {
PROC_VERSION, 7, "version",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
#ifdef CONFIG_PCI
static struct proc_dir_entry proc_root_pci = {
PROC_PCI, 3, "pci",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
+};
+#endif
+#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
};
static struct proc_dir_entry proc_root_self = {
PROC_SELF, 4, "self",
@@ -289,82 +445,103 @@ static struct proc_dir_entry proc_root_self = {
static struct proc_dir_entry proc_root_malloc = {
PROC_MALLOC, 6, "malloc",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
#endif
static struct proc_dir_entry proc_root_kcore = {
PROC_KCORE, 5, "kcore",
S_IFREG | S_IRUSR, 1, 0, 0,
+ 0, &proc_kcore_inode_operations
};
#ifdef CONFIG_MODULES
static struct proc_dir_entry proc_root_modules = {
PROC_MODULES, 7, "modules",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_ksyms = {
PROC_KSYMS, 5, "ksyms",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
#endif
static struct proc_dir_entry proc_root_stat = {
PROC_STAT, 4, "stat",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_devices = {
PROC_DEVICES, 7, "devices",
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,
+ 0, &proc_array_inode_operations
};
#ifdef __SMP_PROF__
static struct proc_dir_entry proc_root_smp = {
PROC_SMP_PROF, 3,"smp",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
#endif
static struct proc_dir_entry proc_root_filesystems = {
PROC_FILESYSTEMS, 11,"filesystems",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_dma = {
PROC_DMA, 3, "dma",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_ioports = {
PROC_IOPORTS, 7, "ioports",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_cmdline = {
PROC_CMDLINE, 7, "cmdline",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
#ifdef CONFIG_RTC
static struct proc_dir_entry proc_root_rtc = {
PROC_RTC, 3, "rtc",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
#endif
static struct proc_dir_entry proc_root_locks = {
PROC_LOCKS, 5, "locks",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_mounts = {
PROC_MTAB, 6, "mounts",
S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
+};
+static struct proc_dir_entry proc_root_swaps = {
+ PROC_SWAP, 5, "swaps",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
static struct proc_dir_entry proc_root_profile = {
PROC_PROFILE, 7, "profile",
S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
+ 0, &proc_profile_inode_operations
+};
+static struct proc_dir_entry proc_root_slab = {
+ PROC_SLABINFO, 8, "slabinfo",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, &proc_array_inode_operations
};
void proc_root_init(void)
{
- static int done = 0;
-
- if (done)
- return;
- done = 1;
proc_base_init();
proc_register(&proc_root, &proc_root_loadavg);
proc_register(&proc_root, &proc_root_uptime);
@@ -374,16 +551,25 @@ void proc_root_init(void)
#ifdef CONFIG_PCI
proc_register(&proc_root, &proc_root_pci);
#endif
+#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_register(&proc_root, &proc_net);
- proc_register(&proc_root, &proc_scsi);
+ proc_net = create_proc_entry("net", S_IFDIR, 0);
+ proc_scsi = create_proc_entry("scsi", S_IFDIR, 0);
+#ifdef CONFIG_SYSCTL
proc_register(&proc_root, &proc_sys_root);
+#endif
+#ifdef CONFIG_MCA
+ proc_register(&proc_root, &proc_mca);
+#endif
#ifdef CONFIG_DEBUG_MALLOC
proc_register(&proc_root, &proc_root_malloc);
#endif
proc_register(&proc_root, &proc_root_kcore);
+ proc_root_kcore.size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
#ifdef CONFIG_MODULES
proc_register(&proc_root, &proc_root_modules);
@@ -405,10 +591,23 @@ void proc_root_init(void)
proc_register(&proc_root, &proc_root_locks);
proc_register(&proc_root, &proc_root_mounts);
+ proc_register(&proc_root, &proc_root_swaps);
+
+#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
+#ifdef CONFIG_SUN_OPENPROMFS
+ openpromfs_init ();
+#endif
+ proc_register(&proc_root, &proc_openprom);
+#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_tty_init();
}
@@ -485,8 +684,17 @@ static int proc_root_lookup(struct inode * dir,const char * name, int len,
{
unsigned int pid, c;
int i, ino, retval;
+ struct task_struct *p;
dir->i_count++;
+
+ if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
+ dir->i_nlink = proc_root.nlink;
+ for_each_task(p)
+ if (p && p->pid)
+ dir->i_nlink++;
+ }
+
retval = proc_lookup(dir, name, len, result);
if (retval != -ENOENT) {
iput(dir);