diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
commit | 99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch) | |
tree | 3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /fs/proc | |
parent | e73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff) |
Merge with Linux 2.3.38.
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/Makefile | 10 | ||||
-rw-r--r-- | fs/proc/base.c | 8 | ||||
-rw-r--r-- | fs/proc/kcore.c | 2 | ||||
-rw-r--r-- | fs/proc/omirr.c | 2 | ||||
-rw-r--r-- | fs/proc/openprom-dev.c | 46 | ||||
-rw-r--r-- | fs/proc/openpromfs.c | 1200 | ||||
-rw-r--r-- | fs/proc/root.c | 3 |
7 files changed, 5 insertions, 1266 deletions
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index e8bb4774f..fade4acf2 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -16,16 +16,6 @@ endif OX_OBJS := procfs_syms.o M_OBJS := -ifeq ($(CONFIG_SUN_OPENPROMFS),y) -O_OBJS += openpromfs.o -OX_OBJS := openprom-dev.o -else - ifeq ($(CONFIG_SUN_OPENPROMFS),m) - M_OBJS += openpromfs.o - OX_OBJS := openprom-dev.o - endif -endif - ifeq ($(CONFIG_PROC_DEVICETREE),y) O_OBJS += proc_devtree.o endif diff --git a/fs/proc/base.c b/fs/proc/base.c index eac10cbd4..1dd50817c 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -513,7 +513,7 @@ static struct pid_entry base_stuff[] = { E(PROC_PID_CMDLINE, "cmdline", S_IFREG|S_IRUGO), E(PROC_PID_STAT, "stat", S_IFREG|S_IRUGO), E(PROC_PID_STATM, "statm", S_IFREG|S_IRUGO), -#ifdef SMP +#ifdef __SMP__ E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUGO), #endif #if CONFIG_AP1000 @@ -643,7 +643,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st * grab the reference to task. */ inode->u.proc_i.task = task; - atomic_inc(&mem_map[MAP_NR(task)].count); + get_task_struct(task); if (!task->p_pptr) goto out_unlock; @@ -865,7 +865,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) case PROC_PID_MAPS: inode->i_op = &proc_maps_inode_operations; break; -#ifdef SMP +#ifdef __SMP__ case PROC_PID_CPU: inode->i_op = &proc_info_inode_operations; inode->u.proc_i.op.proc_read = proc_pid_cpu; @@ -932,7 +932,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry) read_lock(&tasklist_lock); task = find_task_by_pid(pid); if (task) - atomic_inc(&mem_map[MAP_NR(task)].count); + get_task_struct(task); read_unlock(&tasklist_lock); if (!task) goto out; diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 28635ff14..f63bcac6e 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -119,7 +119,7 @@ struct memelfnote extern char saved_command_line[]; -static size_t get_kcore_size(int *num_vma, int *elf_buflen) +static size_t get_kcore_size(int *num_vma, size_t *elf_buflen) { size_t try, size = 0; struct vm_struct *m; diff --git a/fs/proc/omirr.c b/fs/proc/omirr.c index f205dd753..bdbcb0cbf 100644 --- a/fs/proc/omirr.c +++ b/fs/proc/omirr.c @@ -272,8 +272,6 @@ static struct file_operations omirr_operations = { omirr_release, NULL, /* fsync */ NULL, /* fasync */ - NULL, /* check_media_change */ - NULL /* revalidate */ }; struct inode_operations proc_omirr_inode_operations = { diff --git a/fs/proc/openprom-dev.c b/fs/proc/openprom-dev.c deleted file mode 100644 index 79ef8d549..000000000 --- a/fs/proc/openprom-dev.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * linux/fs/proc/openprom-dev.c - * - * handling of devices attached to openpromfs. - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <linux/proc_fs.h> -#include <linux/stat.h> -#include <linux/config.h> -#include <linux/init.h> -#include <linux/module.h> - -struct openpromfs_dev *openprom_devices = NULL; -static ino_t openpromdev_ino = PROC_OPENPROMD_FIRST; - -int proc_openprom_regdev(struct openpromfs_dev *d) -{ - if (openpromdev_ino == PROC_OPENPROMD_FIRST + PROC_NOPENPROMD) - return -1; - d->next = openprom_devices; - d->inode = openpromdev_ino++; - openprom_devices = d; - return 0; -} - -int proc_openprom_unregdev(struct openpromfs_dev *d) -{ - if (d == openprom_devices) { - openprom_devices = d->next; - } else if (!openprom_devices) - return -1; - else { - struct openpromfs_dev *p; - - for (p = openprom_devices; p->next != d && p->next; p = p->next); - if (!p->next) return -1; - p->next = d->next; - } - return 0; -} - -#if defined(CONFIG_SUN_OPENPROMFS_MODULE) -EXPORT_SYMBOL(openprom_devices); -#endif diff --git a/fs/proc/openpromfs.c b/fs/proc/openpromfs.c deleted file mode 100644 index 55f290664..000000000 --- a/fs/proc/openpromfs.c +++ /dev/null @@ -1,1200 +0,0 @@ -/* $Id: openpromfs.c,v 1.36 1999/08/31 07:01:03 davem Exp $ - * openpromfs.c: /proc/openprom handling routines - * - * Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/string.h> -#include <linux/fs.h> -#include <linux/proc_fs.h> -#include <linux/init.h> - -#include <asm/openprom.h> -#include <asm/oplib.h> -#include <asm/uaccess.h> - -#define ALIASES_NNODES 64 - -typedef struct { - u16 parent; - u16 next; - u16 child; - u16 first_prop; - u32 node; -} openpromfs_node; - -typedef struct { -#define OPP_STRING 0x10 -#define OPP_STRINGLIST 0x20 -#define OPP_BINARY 0x40 -#define OPP_HEXSTRING 0x80 -#define OPP_DIRTY 0x01 -#define OPP_QUOTED 0x02 -#define OPP_NOTQUOTED 0x04 -#define OPP_ASCIIZ 0x08 - u32 flag; - u32 alloclen; - u32 len; - char *value; - char name[8]; -} openprom_property; - -static openpromfs_node *nodes = NULL; -static int alloced = 0; -static u16 last_node = 0; -static u16 first_prop = 0; -static u16 options = 0xffff; -static u16 aliases = 0xffff; -static int aliases_nodes = 0; -static char *alias_names [ALIASES_NNODES]; -extern struct openpromfs_dev *openprom_devices; - -#define NODE(ino) nodes[ino - PROC_OPENPROM_FIRST] -#define NODE2INO(node) (node + PROC_OPENPROM_FIRST) -#define NODEP2INO(no) (no + PROC_OPENPROM_FIRST + last_node) - -static int openpromfs_create (struct inode *, struct dentry *, int); -static int openpromfs_readdir(struct file *, void *, filldir_t); -static struct dentry *openpromfs_lookup(struct inode *, struct dentry *dentry); -static int openpromfs_unlink (struct inode *, struct dentry *dentry); - -static ssize_t nodenum_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - struct inode *inode = file->f_dentry->d_inode; - char buffer[10]; - - if (count < 0 || !inode->u.generic_ip) - return -EINVAL; - sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip)); - if (file->f_pos >= 9) - return 0; - if (count > 9 - file->f_pos) - count = 9 - file->f_pos; - copy_to_user(buf, buffer + file->f_pos, count); - file->f_pos += count; - return count; -} - -static ssize_t property_read(struct file *filp, char *buf, - size_t count, loff_t *ppos) -{ - struct inode *inode = filp->f_dentry->d_inode; - int i, j, k; - u32 node; - char *p, *s; - u32 *q; - openprom_property *op; - char buffer[64]; - - if (filp->f_pos >= 0xffffff) - return -EINVAL; - if (!filp->private_data) { - node = nodes[(u16)((long)inode->u.generic_ip)].node; - i = ((u32)(long)inode->u.generic_ip) >> 16; - if ((u16)((long)inode->u.generic_ip) == aliases) { - if (i >= aliases_nodes) - p = 0; - else - p = alias_names [i]; - } else - for (p = prom_firstprop (node, buffer); - i && p && *p; - p = prom_nextprop (node, p, buffer), i--) - /* nothing */ ; - if (!p || !*p) - return -EIO; - i = prom_getproplen (node, p); - if (i < 0) { - if ((u16)((long)inode->u.generic_ip) == aliases) - i = 0; - else - return -EIO; - } - k = i; - if (i < 64) i = 64; - filp->private_data = kmalloc (sizeof (openprom_property) - + (j = strlen (p)) + 2 * i, - GFP_KERNEL); - if (!filp->private_data) - return -ENOMEM; - op = (openprom_property *)filp->private_data; - op->flag = 0; - op->alloclen = 2 * i; - strcpy (op->name, p); - op->value = (char *)(((unsigned long)(op->name + j + 4)) & ~3); - op->len = k; - if (k && prom_getproperty (node, p, op->value, i) < 0) - return -EIO; - op->value [k] = 0; - if (k) { - for (s = 0, p = op->value; p < op->value + k; p++) { - if ((*p >= ' ' && *p <= '~') || *p == '\n') { - op->flag |= OPP_STRING; - s = p; - continue; - } - if (p > op->value && !*p && s == p - 1) { - if (p < op->value + k - 1) - op->flag |= OPP_STRINGLIST; - else - op->flag |= OPP_ASCIIZ; - continue; - } - if (k == 1 && !*p) { - op->flag |= (OPP_STRING|OPP_ASCIIZ); - break; - } - op->flag &= ~(OPP_STRING|OPP_STRINGLIST); - if (k & 3) - op->flag |= OPP_HEXSTRING; - else - op->flag |= OPP_BINARY; - break; - } - if (op->flag & OPP_STRINGLIST) - op->flag &= ~(OPP_STRING); - if (op->flag & OPP_ASCIIZ) - op->len--; - } - } else - op = (openprom_property *)filp->private_data; - if (!count || !(op->len || (op->flag & OPP_ASCIIZ))) - return 0; - if (op->flag & OPP_STRINGLIST) { - for (k = 0, p = op->value; p < op->value + op->len; p++) - if (!*p) - k++; - i = op->len + 4 * k + 3; - } else if (op->flag & OPP_STRING) { - i = op->len + 3; - } else if (op->flag & OPP_BINARY) { - i = (op->len * 9) >> 2; - } else { - i = (op->len << 1) + 1; - } - k = filp->f_pos; - if (k >= i) return 0; - if (count > i - k) count = i - k; - if (op->flag & OPP_STRING) { - if (!k) { - __put_user('\'', buf); - k++; - count--; - } - - if (k + count >= i - 2) - j = i - 2 - k; - else - j = count; - - if (j >= 0) { - copy_to_user(buf + k - filp->f_pos, - op->value + k - 1, j); - count -= j; - k += j; - } - - if (count) - __put_user('\'', &buf [k++ - filp->f_pos]); - if (count > 1) - __put_user('\n', &buf [k++ - filp->f_pos]); - - } else if (op->flag & OPP_STRINGLIST) { - char *tmp; - - tmp = kmalloc (i, GFP_KERNEL); - if (!tmp) - return -ENOMEM; - - s = tmp; - *s++ = '\''; - for (p = op->value; p < op->value + op->len; p++) { - if (!*p) { - strcpy(s, "' + '"); - s += 5; - continue; - } - *s++ = *p; - } - strcpy(s, "'\n"); - - copy_to_user(buf, tmp + k, count); - - kfree(tmp); - k += count; - - } else if (op->flag & OPP_BINARY) { - char buffer[10]; - u32 *first, *last; - int first_off, last_cnt; - - first = ((u32 *)op->value) + k / 9; - first_off = k % 9; - last = ((u32 *)op->value) + (k + count - 1) / 9; - last_cnt = (k + count) % 9; - if (!last_cnt) last_cnt = 9; - - if (first == last) { - sprintf (buffer, "%08x.", *first); - copy_to_user (buf, buffer + first_off, last_cnt - first_off); - buf += last_cnt - first_off; - } else { - for (q = first; q <= last; q++) { - sprintf (buffer, "%08x.", *q); - if (q == first) { - copy_to_user (buf, buffer + first_off, - 9 - first_off); - buf += 9 - first_off; - } else if (q == last) { - copy_to_user (buf, buffer, last_cnt); - buf += last_cnt; - } else { - copy_to_user (buf, buffer, 9); - buf += 9; - } - } - } - - if (last == (u32 *)(op->value + op->len - 4) && last_cnt == 9) - __put_user('\n', (buf - 1)); - - k += count; - - } else if (op->flag & OPP_HEXSTRING) { - char buffer[2]; - - if ((k < i - 1) && (k & 1)) { - sprintf (buffer, "%02x", *(op->value + (k >> 1))); - __put_user(buffer[1], &buf[k++ - filp->f_pos]); - count--; - } - - for (; (count > 1) && (k < i - 1); k += 2) { - sprintf (buffer, "%02x", *(op->value + (k >> 1))); - copy_to_user (buf + k - filp->f_pos, buffer, 2); - count -= 2; - } - - if (count && (k < i - 1)) { - sprintf (buffer, "%02x", *(op->value + (k >> 1))); - __put_user(buffer[0], &buf[k++ - filp->f_pos]); - count--; - } - - if (count) - __put_user('\n', &buf [k++ - filp->f_pos]); - } - count = k - filp->f_pos; - filp->f_pos = k; - return count; -} - -static ssize_t property_write(struct file *filp, const char *buf, - size_t count, loff_t *ppos) -{ - int i, j, k; - char *p; - u32 *q; - void *b; - openprom_property *op; - - if (filp->f_pos >= 0xffffff) - return -EINVAL; - if (!filp->private_data) { - i = property_read (filp, NULL, 0, 0); - if (i) - return i; - } - k = filp->f_pos; - op = (openprom_property *)filp->private_data; - if (!(op->flag & OPP_STRING)) { - u32 *first, *last; - int first_off, last_cnt; - u32 mask, mask2; - char tmp [9]; - int forcelen = 0; - - j = k % 9; - for (i = 0; i < count; i++, j++) { - if (j == 9) j = 0; - if (!j) { - char ctmp; - __get_user(ctmp, &buf[i]); - if (ctmp != '.') { - if (ctmp != '\n') { - if (op->flag & OPP_BINARY) - return -EINVAL; - else - goto write_try_string; - } else { - count = i + 1; - forcelen = 1; - break; - } - } - } else { - char ctmp; - __get_user(ctmp, &buf[i]); - if (ctmp < '0' || - (ctmp > '9' && ctmp < 'A') || - (ctmp > 'F' && ctmp < 'a') || - ctmp > 'f') { - if (op->flag & OPP_BINARY) - return -EINVAL; - else - goto write_try_string; - } - } - } - op->flag |= OPP_BINARY; - tmp [8] = 0; - i = ((count + k + 8) / 9) << 2; - if (op->alloclen <= i) { - b = kmalloc (sizeof (openprom_property) + 2 * i, - GFP_KERNEL); - if (!b) - return -ENOMEM; - memcpy (b, filp->private_data, - sizeof (openprom_property) - + strlen (op->name) + op->alloclen); - memset (((char *)b) + sizeof (openprom_property) - + strlen (op->name) + op->alloclen, - 0, 2 * i - op->alloclen); - op = (openprom_property *)b; - op->alloclen = 2*i; - b = filp->private_data; - filp->private_data = (void *)op; - kfree (b); - } - first = ((u32 *)op->value) + (k / 9); - first_off = k % 9; - last = (u32 *)(op->value + i); - last_cnt = (k + count) % 9; - if (first + 1 == last) { - memset (tmp, '0', 8); - copy_from_user (tmp + first_off, buf, - (count + first_off > 8) ? 8 - first_off : count); - mask = 0xffffffff; - mask2 = 0xffffffff; - for (j = 0; j < first_off; j++) - mask >>= 1; - for (j = 8 - count - first_off; j > 0; j--) - mask2 <<= 1; - mask &= mask2; - if (mask) { - *first &= ~mask; - *first |= simple_strtoul (tmp, 0, 16); - op->flag |= OPP_DIRTY; - } - } else { - op->flag |= OPP_DIRTY; - for (q = first; q < last; q++) { - if (q == first) { - if (first_off < 8) { - memset (tmp, '0', 8); - copy_from_user (tmp + first_off, buf, - 8 - first_off); - mask = 0xffffffff; - for (j = 0; j < first_off; j++) - mask >>= 1; - *q &= ~mask; - *q |= simple_strtoul (tmp,0,16); - } - buf += 9; - } else if ((q == last - 1) && last_cnt - && (last_cnt < 8)) { - memset (tmp, '0', 8); - copy_from_user (tmp, buf, last_cnt); - mask = 0xffffffff; - for (j = 0; j < 8 - last_cnt; j++) - mask <<= 1; - *q &= ~mask; - *q |= simple_strtoul (tmp, 0, 16); - buf += last_cnt; - } else { - char tchars[17]; /* XXX yuck... */ - - copy_from_user(tchars, buf, 16); - *q = simple_strtoul (tchars, 0, 16); - buf += 9; - } - } - } - if (!forcelen) { - if (op->len < i) - op->len = i; - } else - op->len = i; - filp->f_pos += count; - } -write_try_string: - if (!(op->flag & OPP_BINARY)) { - if (!(op->flag & (OPP_QUOTED | OPP_NOTQUOTED))) { - char ctmp; - - /* No way, if somebody starts writing from the middle, - * we don't know whether he uses quotes around or not - */ - if (k > 0) - return -EINVAL; - __get_user(ctmp, buf); - if (ctmp == '\'') { - op->flag |= OPP_QUOTED; - buf++; - count--; - filp->f_pos++; - if (!count) { - op->flag |= OPP_STRING; - return 1; - } - } else - op->flag |= OPP_NOTQUOTED; - } - op->flag |= OPP_STRING; - if (op->alloclen <= count + filp->f_pos) { - b = kmalloc (sizeof (openprom_property) - + 2 * (count + filp->f_pos), GFP_KERNEL); - if (!b) - return -ENOMEM; - memcpy (b, filp->private_data, - sizeof (openprom_property) - + strlen (op->name) + op->alloclen); - memset (((char *)b) + sizeof (openprom_property) - + strlen (op->name) + op->alloclen, - 0, 2*(count - filp->f_pos) - op->alloclen); - op = (openprom_property *)b; - op->alloclen = 2*(count + filp->f_pos); - b = filp->private_data; - filp->private_data = (void *)op; - kfree (b); - } - p = op->value + filp->f_pos - ((op->flag & OPP_QUOTED) ? 1 : 0); - copy_from_user (p, buf, count); - op->flag |= OPP_DIRTY; - for (i = 0; i < count; i++, p++) - if (*p == '\n') { - *p = 0; - break; - } - if (i < count) { - op->len = p - op->value; - filp->f_pos += i + 1; - if ((p > op->value) && (op->flag & OPP_QUOTED) - && (*(p - 1) == '\'')) - op->len--; - } else { - if (p - op->value > op->len) - op->len = p - op->value; - filp->f_pos += count; - } - } - return filp->f_pos - k; -} - -int property_release (struct inode *inode, struct file *filp) -{ - openprom_property *op = (openprom_property *)filp->private_data; - unsigned long flags; - int error; - u32 node; - - if (!op) - return 0; - node = nodes[(u16)((long)inode->u.generic_ip)].node; - if ((u16)((long)inode->u.generic_ip) == aliases) { - if ((op->flag & OPP_DIRTY) && (op->flag & OPP_STRING)) { - char *p = op->name; - int i = (op->value - op->name) - strlen (op->name) - 1; - op->value [op->len] = 0; - *(op->value - 1) = ' '; - if (i) { - for (p = op->value - i - 2; p >= op->name; p--) - p[i] = *p; - p = op->name + i; - } - memcpy (p - 8, "nvalias ", 8); - prom_feval (p - 8); - } - } else if (op->flag & OPP_DIRTY) { - if (op->flag & OPP_STRING) { - op->value [op->len] = 0; - save_and_cli (flags); - error = prom_setprop (node, op->name, - op->value, op->len + 1); - restore_flags (flags); - if (error <= 0) - printk (KERN_WARNING "/proc/openprom: " - "Couldn't write property %s\n", - op->name); - } else if ((op->flag & OPP_BINARY) || !op->len) { - save_and_cli (flags); - error = prom_setprop (node, op->name, - op->value, op->len); - restore_flags (flags); - if (error <= 0) - printk (KERN_WARNING "/proc/openprom: " - "Couldn't write property %s\n", - op->name); - } else { - printk (KERN_WARNING "/proc/openprom: " - "Unknown property type of %s\n", - op->name); - } - } - kfree (filp->private_data); - return 0; -} - -static struct file_operations openpromfs_prop_ops = { - NULL, /* lseek - default */ - property_read, /* read */ - property_write, /* write - bad */ - NULL, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - property_release, /* no special release code */ - NULL /* can't fsync */ -}; - -static struct inode_operations openpromfs_prop_inode_ops = { - &openpromfs_prop_ops, /* default property file-ops */ -}; - -static struct file_operations openpromfs_nodenum_ops = { - NULL, /* lseek - default */ - nodenum_read, /* read */ - NULL, /* write - bad */ - NULL, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -static struct inode_operations openpromfs_nodenum_inode_ops = { - &openpromfs_nodenum_ops,/* default .node file-ops */ -}; - -static struct file_operations openprom_alias_operations = { - NULL, /* lseek - default */ - NULL, /* read - bad */ - NULL, /* write - bad */ - openpromfs_readdir, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -static struct inode_operations openprom_alias_inode_operations = { - &openprom_alias_operations,/* default aliases directory file-ops */ - openpromfs_create, /* create */ - openpromfs_lookup, /* lookup */ - NULL, /* link */ - openpromfs_unlink, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ -}; - -extern struct inode_operations openprom_inode_operations; - -static int lookup_children(u16 n, const char * name, int len) -{ - int ret; - u16 node; - for (; n != 0xffff; n = nodes[n].next) { - node = nodes[n].child; - if (node != 0xffff) { - char buffer[128]; - int i; - char *p; - - while (node != 0xffff) { - if (prom_getname (nodes[node].node, - buffer, 128) >= 0) { - i = strlen (buffer); - if ((len == i) - && !strncmp (buffer, name, len)) - return NODE2INO(node); - p = strchr (buffer, '@'); - if (p && (len == p - buffer) - && !strncmp (buffer, name, len)) - return NODE2INO(node); - } - node = nodes[node].next; - } - } else - continue; - ret = lookup_children (nodes[n].child, name, len); - if (ret) return ret; - } - return 0; -} - -static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentry) -{ - int ino = 0; -#define OPFSL_DIR 0 -#define OPFSL_PROPERTY 1 -#define OPFSL_NODENUM 2 -#define OPFSL_DEVICE 3 - int type = 0; - char buffer[128]; - char *p; - const char *name; - u32 n; - u16 dirnode; - unsigned int len; - int i; - struct inode *inode; - struct openpromfs_dev *d = NULL; - char buffer2[64]; - - inode = NULL; - name = dentry->d_name.name; - len = dentry->d_name.len; - if (name [0] == '.' && len == 5 && !strncmp (name + 1, "node", 4)) { - ino = NODEP2INO(NODE(dir->i_ino).first_prop); - type = OPFSL_NODENUM; - } - if (!ino) { - u16 node = NODE(dir->i_ino).child; - while (node != 0xffff) { - if (prom_getname (nodes[node].node, buffer, 128) >= 0) { - i = strlen (buffer); - if (len == i && !strncmp (buffer, name, len)) { - ino = NODE2INO(node); - type = OPFSL_DIR; - break; - } - p = strchr (buffer, '@'); - if (p && (len == p - buffer) - && !strncmp (buffer, name, len)) { - ino = NODE2INO(node); - type = OPFSL_DIR; - break; - } - } - node = nodes[node].next; - } - } - n = NODE(dir->i_ino).node; - dirnode = dir->i_ino - PROC_OPENPROM_FIRST; - if (!ino) { - int j = NODEP2INO(NODE(dir->i_ino).first_prop); - if (dirnode != aliases) { - for (p = prom_firstprop (n, buffer2); - p && *p; - p = prom_nextprop (n, p, buffer2)) { - j++; - if ((len == strlen (p)) - && !strncmp (p, name, len)) { - ino = j; - type = OPFSL_PROPERTY; - break; - } - } - } else { - int k; - for (k = 0; k < aliases_nodes; k++) { - j++; - if (alias_names [k] - && (len == strlen (alias_names [k])) - && !strncmp (alias_names [k], name, len)) { - ino = j; - type = OPFSL_PROPERTY; - break; - } - } - } - } - if (!ino) { - for (d = openprom_devices; d; d = d->next) - if ((d->node == n) && (strlen (d->name) == len) - && !strncmp (d->name, name, len)) { - ino = d->inode; - type = OPFSL_DEVICE; - break; - } - } - if (!ino) { - ino = lookup_children (NODE(dir->i_ino).child, name, len); - if (ino) - type = OPFSL_DIR; - else - return ERR_PTR(-ENOENT); - } - inode = iget (dir->i_sb, ino, 0); - if (!inode) - return ERR_PTR(-EINVAL); - switch (type) { - case OPFSL_DIR: - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; - if (ino == PROC_OPENPROM_FIRST + aliases) { - inode->i_mode |= S_IWUSR; - inode->i_op = &openprom_alias_inode_operations; - } else - inode->i_op = &openprom_inode_operations; - inode->i_nlink = 2; - break; - case OPFSL_NODENUM: - inode->i_mode = S_IFREG | S_IRUGO; - inode->i_op = &openpromfs_nodenum_inode_ops; - inode->i_nlink = 1; - inode->u.generic_ip = (void *)(long)(n); - break; - case OPFSL_PROPERTY: - if ((dirnode == options) && (len == 17) - && !strncmp (name, "security-password", 17)) - inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR; - else { - inode->i_mode = S_IFREG | S_IRUGO; - if (dirnode == options || dirnode == aliases) { - if (len != 4 || strncmp (name, "name", 4)) - inode->i_mode |= S_IWUSR; - } - } - inode->i_op = &openpromfs_prop_inode_ops; - inode->i_nlink = 1; - if (inode->i_size < 0) - inode->i_size = 0; - inode->u.generic_ip = (void *)(long)(((u16)dirnode) | - (((u16)(ino - NODEP2INO(NODE(dir->i_ino).first_prop) - 1)) << 16)); - break; - case OPFSL_DEVICE: - init_special_inode(d->mode, kdev_to_nr(d->rdev)); - } - - inode->i_gid = 0; - inode->i_uid = 0; - - d_add(dentry, inode); - return NULL; -} - -static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filldir) -{ - struct inode *inode = filp->f_dentry->d_inode; - unsigned int ino; - u32 n; - int i, j; - char buffer[128]; - u16 node; - char *p; - struct openpromfs_dev *d; - char buffer2[64]; - - ino = inode->i_ino; - i = filp->f_pos; - switch (i) { - case 0: - if (filldir(dirent, ".", 1, i, ino) < 0) return 0; - i++; - filp->f_pos++; - /* fall thru */ - case 1: - if (filldir(dirent, "..", 2, i, - (NODE(ino).parent == 0xffff) ? - PROC_ROOT_INO : NODE2INO(NODE(ino).parent)) < 0) - return 0; - i++; - filp->f_pos++; - /* fall thru */ - default: - i -= 2; - node = NODE(ino).child; - while (i && node != 0xffff) { - node = nodes[node].next; - i--; - } - while (node != 0xffff) { - if (prom_getname (nodes[node].node, buffer, 128) < 0) - return 0; - if (filldir(dirent, buffer, strlen(buffer), - filp->f_pos, NODE2INO(node)) < 0) - return 0; - filp->f_pos++; - node = nodes[node].next; - } - j = NODEP2INO(NODE(ino).first_prop); - if (!i) { - if (filldir(dirent, ".node", 5, filp->f_pos, j) < 0) - return 0; - filp->f_pos++; - } else - i--; - n = NODE(ino).node; - if (ino == PROC_OPENPROM_FIRST + aliases) { - for (j++; i < aliases_nodes; i++, j++) { - if (alias_names [i]) { - if (filldir (dirent, alias_names [i], - strlen (alias_names [i]), - filp->f_pos, j) < 0) return 0; - filp->f_pos++; - } - } - } else { - for (p = prom_firstprop (n, buffer2); - p && *p; - p = prom_nextprop (n, p, buffer2)) { - j++; - if (i) i--; - else { - if (filldir(dirent, p, strlen(p), - filp->f_pos, j) < 0) - return 0; - filp->f_pos++; - } - } - } - for (d = openprom_devices; d; d = d->next) { - if (d->node == n) { - if (i) i--; - else { - if (filldir(dirent, d->name, - strlen(d->name), - filp->f_pos, d->inode) < 0) - return 0; - filp->f_pos++; - } - } - } - } - return 0; -} - -static int openpromfs_create (struct inode *dir, struct dentry *dentry, int mode) -{ - char *p; - struct inode *inode; - - if (!dir) - return -ENOENT; - if (dentry->d_name.len > 256) - return -EINVAL; - if (aliases_nodes == ALIASES_NNODES) - return -EIO; - p = kmalloc (dentry->d_name.len + 1, GFP_KERNEL); - if (!p) - return -ENOMEM; - strncpy (p, dentry->d_name.name, dentry->d_name.len); - p [dentry->d_name.len] = 0; - alias_names [aliases_nodes++] = p; - inode = iget (dir->i_sb, - NODEP2INO(NODE(dir->i_ino).first_prop) + aliases_nodes); - if (!inode) - return -EINVAL; - inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR; - inode->i_op = &openpromfs_prop_inode_ops; - inode->i_nlink = 1; - if (inode->i_size < 0) inode->i_size = 0; - inode->u.generic_ip = (void *)(long)(((u16)aliases) | - (((u16)(aliases_nodes - 1)) << 16)); - d_instantiate(dentry, inode); - return 0; -} - -static int openpromfs_unlink (struct inode *dir, struct dentry *dentry) -{ - unsigned int len; - char *p; - const char *name; - int i; - - name = dentry->d_name.name; - len = dentry->d_name.len; - for (i = 0; i < aliases_nodes; i++) - if ((strlen (alias_names [i]) == len) - && !strncmp (name, alias_names[i], len)) { - char buffer[512]; - - p = alias_names [i]; - alias_names [i] = NULL; - kfree (p); - strcpy (buffer, "nvunalias "); - memcpy (buffer + 10, name, len); - buffer [10 + len] = 0; - prom_feval (buffer); - } - d_delete(dentry); - return 0; -} - -/* {{{ init section */ -#ifndef MODULE -static int __init check_space (u16 n) -#else -static int check_space (u16 n) -#endif -{ - unsigned long pages; - - if ((1 << alloced) * PAGE_SIZE < (n + 2) * sizeof(openpromfs_node)) { - pages = __get_free_pages (GFP_KERNEL, alloced + 1); - if (!pages) - return -1; - - if (nodes) { - memcpy ((char *)pages, (char *)nodes, - (1 << alloced) * PAGE_SIZE); - free_pages ((unsigned long)nodes, alloced); - } - alloced++; - nodes = (openpromfs_node *)pages; - } - return 0; -} - -#ifndef MODULE -static u16 __init get_nodes (u16 parent, u32 node) -#else -static u16 get_nodes (u16 parent, u32 node) -#endif -{ - char *p; - u16 n = last_node++, i; - char buffer[64]; - - if (check_space (n) < 0) - return 0xffff; - nodes[n].parent = parent; - nodes[n].node = node; - nodes[n].next = 0xffff; - nodes[n].child = 0xffff; - nodes[n].first_prop = first_prop++; - if (!parent) { - char buffer[8]; - int j; - - if ((j = prom_getproperty (node, "name", buffer, 8)) >= 0) { - buffer[j] = 0; - if (!strcmp (buffer, "options")) - options = n; - else if (!strcmp (buffer, "aliases")) - aliases = n; - } - } - if (n != aliases) - for (p = prom_firstprop (node, buffer); - p && p != (char *)-1 && *p; - p = prom_nextprop (node, p, buffer)) - first_prop++; - else { - char *q; - for (p = prom_firstprop (node, buffer); - p && p != (char *)-1 && *p; - p = prom_nextprop (node, p, buffer)) { - if (aliases_nodes == ALIASES_NNODES) - break; - for (i = 0; i < aliases_nodes; i++) - if (!strcmp (p, alias_names [i])) - break; - if (i < aliases_nodes) - continue; - q = kmalloc (strlen (p) + 1, GFP_KERNEL); - if (!q) - return 0xffff; - strcpy (q, p); - alias_names [aliases_nodes++] = q; - } - first_prop += ALIASES_NNODES; - } - node = prom_getchild (node); - if (node) { - parent = get_nodes (n, node); - if (parent == 0xffff) - return 0xffff; - nodes[n].child = parent; - while ((node = prom_getsibling (node)) != 0) { - i = get_nodes (n, node); - if (i == 0xffff) - return 0xffff; - nodes[parent].next = i; - parent = i; - } - } - return n; -} - - -#ifdef MODULE -void openpromfs_use (struct inode *inode, int inc) -{ - static int root_fresh = 1; - static int dec_first = 1; - if (inc) { - if (inode->i_count == 1) - MOD_INC_USE_COUNT; - else if (root_fresh && inode->i_ino == PROC_OPENPROM_FIRST) { - root_fresh = 0; - MOD_INC_USE_COUNT; - } - } else { - if (inode->i_ino == PROC_OPENPROM_FIRST) - root_fresh = 0; - if (!dec_first) - MOD_DEC_USE_COUNT; - } - dec_first = 0; -} - -#else -#define openpromfs_use 0 -#endif - -static struct file_operations openprom_operations = { - NULL, /* lseek - default */ - NULL, /* read - bad */ - NULL, /* write - bad */ - openpromfs_readdir, /* readdir */ -}; - -static struct inode_operations openprom_inode_operations = { - &openprom_operations,/* default net directory file-ops */ - NULL, /* create */ - openpromfs_lookup, /* lookup */ -}; - -static void openprom_read_inode(struct inode * inode) -{ - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - if (inode->i_ino == PROC_OPENPROM) { - inode->i_op = &openprom_inode_operations; - } -} - -static void openprom_put_super(struct super_block *sb) -{ - MOD_DEC_USE_COUNT; -} - -static int openprom_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) -{ - struct statfs tmp; - - tmp.f_type = PROC_SUPER_MAGIC; /* FIXME */ - tmp.f_bsize = PAGE_SIZE/sizeof(long); /* ??? */ - tmp.f_blocks = 0; - tmp.f_bfree = 0; - tmp.f_bavail = 0; - tmp.f_files = 0; - tmp.f_ffree = 0; - tmp.f_namelen = NAME_MAX; - return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0; -} - -static struct super_operations openprom_sops = { - openprom_read_inode, - NULL, - NULL, - NULL, - NULL, - openprom_put_super, - NULL, - openprom_statfs, - NULL -}; - -struct super_block *openprom_read_super(struct super_block *s,void *data, - int silent) -{ - struct inode * root_inode; - - MOD_INC_USE_COUNT; - lock_super(s); - s->s_blocksize = 1024; - s->s_blocksize_bits = 10; - s->s_magic = PROC_SUPER_MAGIC; /* FIXME */ - s->s_op = &openprom_sops; - root_inode = iget(s, PROC_OPENPROM); - if (!root_inode) - goto out_no_root; - s->s_root = d_alloc_root(root_inode); - if (!s->s_root) - goto out_no_root; - unlock_super(s); - return s; - -out_no_root: - printk("proc_read_super: get root inode failed\n"); - iput(root_inode); - s->s_dev = 0; - unlock_super(s); - return NULL; -} - -static struct file_system_type openprom_fs_type = { - "openprom", - 0, - openprom_read_super, - NULL -}; - -static int init_openprom_fs(void) -{ - nodes = (openpromfs_node *)__get_free_pages(GFP_KERNEL, 0); - if (!nodes) { - printk (KERN_WARNING "/proc/openprom: can't get free page\n"); - return -EIO; - } - if (get_nodes (0xffff, prom_root_node) == 0xffff) { - printk (KERN_WARNING "/proc/openprom: couldn't setup tree\n"); - return -EIO; - } - nodes[last_node].first_prop = first_prop; - return register_filesystem(&openprom_fs_type); -} - -#ifdef MODULE - -EXPORT_NO_SYMBOLS; - -int init_module (void) -{ - return init_openprom_fs(); -} - -#else - -void __init openpromfs_init (void) -{ - init_openprom_fs(); -} -#endif - -#ifdef MODULE -void cleanup_module (void) -{ - int i; - unregister_filesystem(&openprom_fs_type); - free_pages ((unsigned long)nodes, alloced); - for (i = 0; i < aliases_nodes; i++) - if (alias_names [i]) - kfree (alias_names [i]); - nodes = NULL; -} -#endif diff --git a/fs/proc/root.c b/fs/proc/root.c index 83a0d7619..75780167a 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -73,9 +73,6 @@ void __init proc_root_init(void) proc_root_fs = proc_mkdir("fs", 0); proc_root_driver = proc_mkdir("driver", 0); #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) -#ifdef CONFIG_SUN_OPENPROMFS - openpromfs_init (); -#endif /* just give it a mountpoint */ proc_mkdir("openprom", 0); #endif |