patch-2.3.27 linux/fs/proc/root.c
Next file: linux/fs/proc/scsi.c
Previous file: linux/fs/proc/procfs_syms.c
Back to the patch index
Back to the overall index
- Lines: 496
- Date:
Thu Nov 11 16:57:31 1999
- Orig file:
v2.3.26/linux/fs/proc/root.c
- Orig date:
Mon Nov 1 13:56:27 1999
diff -u --recursive --new-file v2.3.26/linux/fs/proc/root.c linux/fs/proc/root.c
@@ -22,11 +22,6 @@
#include <linux/zorro.h>
#endif
-/*
- * Offset of the first process in the /proc root directory..
- */
-#define FIRST_PROCESS_ENTRY 256
-
static int proc_root_readdir(struct file *, void *, filldir_t);
static struct dentry *proc_root_lookup(struct inode *,struct dentry *);
static int proc_unlink(struct inode *, struct dentry *);
@@ -37,22 +32,12 @@
* These are the generic /proc directory operations. They
* use the in-memory "struct proc_dir_entry" tree to parse
* the /proc directory.
- *
- * NOTE! The /proc/scsi directory currently does not correctly
- * build up the proc_dir_entry tree, and will show up empty.
*/
static struct file_operations proc_dir_operations = {
NULL, /* lseek - default */
NULL, /* read - bad */
NULL, /* write - bad */
proc_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 */
};
/*
@@ -62,23 +47,6 @@
&proc_dir_operations, /* default net directory file-ops */
NULL, /* create */
proc_lookup, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
};
/*
@@ -90,21 +58,6 @@
proc_lookup, /* lookup */
NULL, /* link */
proc_unlink, /* unlink(struct inode *, struct dentry *) */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
};
/*
@@ -117,13 +70,6 @@
NULL, /* read - bad */
NULL, /* write - bad */
proc_root_readdir, /* readdir */
- NULL, /* poll - default */
- NULL, /* ioctl - default */
- NULL, /* mmap */
- NULL, /* no special open code */
- NULL, /* flush */
- NULL, /* no special release code */
- NULL /* no fsync */
};
/*
@@ -133,23 +79,6 @@
&proc_root_operations, /* default base directory file-ops */
NULL, /* create */
proc_root_lookup, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
};
/*
@@ -164,8 +93,7 @@
&proc_root, NULL
};
-struct proc_dir_entry *proc_net, *proc_scsi, *proc_bus, *proc_sysvipc,
- *proc_root_fs, *proc_root_driver;
+struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver;
#ifdef CONFIG_MCA
struct proc_dir_entry *proc_mca;
@@ -268,36 +196,12 @@
NULL, /* read - bad */
NULL, /* write - bad */
OPENPROM_DEFREADDIR, /* 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 */
};
struct inode_operations proc_openprom_inode_operations = {
&proc_openprom_operations,/* default net directory file-ops */
NULL, /* create */
OPENPROM_DEFLOOKUP, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
};
struct proc_dir_entry proc_openprom = {
@@ -321,6 +225,73 @@
return PROC_DYNAMIC_FIRST + i;
}
+int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
+{
+ struct inode *inode = dentry->d_inode;
+ struct proc_dir_entry * de;
+ char *page;
+ int len = 0;
+
+ de = (struct proc_dir_entry *) inode->u.generic_ip;
+ if (!de)
+ return -ENOENT;
+ if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+
+ if (de->readlink_proc)
+ len = de->readlink_proc(de, page);
+
+ if (len > buflen)
+ len = buflen;
+
+ copy_to_user(buffer, page, len);
+ free_page((unsigned long) page);
+ return len;
+}
+
+struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow)
+{
+ struct inode *inode = dentry->d_inode;
+ struct proc_dir_entry * de;
+ char *page;
+ struct dentry *d;
+ int len = 0;
+
+ de = (struct proc_dir_entry *) inode->u.generic_ip;
+ if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+ return NULL;
+
+ if (de->readlink_proc)
+ len = de->readlink_proc(de, page);
+
+ d = lookup_dentry(page, base, follow);
+ free_page((unsigned long) page);
+ return d;
+}
+
+static struct inode_operations proc_link_inode_operations = {
+ NULL, /* no file-ops */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ proc_readlink, /* readlink */
+ proc_follow_link, /* follow_link */
+ NULL, /* get_block */
+ NULL, /* readpage */
+ NULL, /* writepage */
+ NULL, /* flushpage */
+ NULL, /* truncate */
+ NULL, /* permission */
+ NULL, /* smap */
+ NULL /* revalidate */
+};
+
int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
int i;
@@ -433,50 +404,6 @@
return lookup_dentry(tmp, base, follow);
}
-int proc_readlink(struct dentry * dentry, char * buffer, int buflen)
-{
- struct inode *inode = dentry->d_inode;
- struct proc_dir_entry * de;
- char *page;
- int len = 0;
-
- de = (struct proc_dir_entry *) inode->u.generic_ip;
- if (!de)
- return -ENOENT;
- if (!(page = (char*) __get_free_page(GFP_KERNEL)))
- return -ENOMEM;
-
- if (de->readlink_proc)
- len = de->readlink_proc(de, page);
-
- if (len > buflen)
- len = buflen;
-
- copy_to_user(buffer, page, len);
- free_page((unsigned long) page);
- return len;
-}
-
-struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow)
-{
- struct inode *inode = dentry->d_inode;
- struct proc_dir_entry * de;
- char *page;
- struct dentry *d;
- int len = 0;
-
- de = (struct proc_dir_entry *) inode->u.generic_ip;
- if (!(page = (char*) __get_free_page(GFP_KERNEL)))
- return NULL;
-
- if (de->readlink_proc)
- len = de->readlink_proc(de, page);
-
- d = lookup_dentry(page, base, follow);
- free_page((unsigned long) page);
- return d;
-}
-
static struct inode_operations proc_self_inode_operations = {
NULL, /* no file-ops */
NULL, /* create */
@@ -500,29 +427,6 @@
NULL /* revalidate */
};
-static struct inode_operations proc_link_inode_operations = {
- NULL, /* no file-ops */
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- proc_readlink, /* readlink */
- proc_follow_link, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
-};
-
static struct proc_dir_entry proc_root_self = {
0, 4, "self",
S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0,
@@ -533,21 +437,16 @@
0, 8, "ppc_htab",
S_IFREG | S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 1, 0, 0,
0, &proc_ppc_htab_inode_operations,
- NULL, NULL, /* get_info, fill_inode */
- NULL, /* next */
- NULL, NULL /* parent, subdir */
};
#endif
void __init proc_root_init(void)
{
- proc_base_init();
proc_misc_init();
proc_register(&proc_root, &proc_root_self);
proc_net = create_proc_entry("net", S_IFDIR, 0);
- proc_scsi = create_proc_entry("scsi", S_IFDIR, 0);
#ifdef CONFIG_SYSVIPC
- proc_sysvipc = create_proc_entry("sysvipc", S_IFDIR, 0);
+ create_proc_entry("sysvipc", S_IFDIR, 0);
#endif
#ifdef CONFIG_SYSCTL
proc_sys_root = create_proc_entry("sys", S_IFDIR, 0);
@@ -613,7 +512,7 @@
if (de->namelen != dentry->d_name.len)
continue;
if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
- int ino = de->low_ino | (dir->i_ino & ~(0xffff));
+ int ino = de->low_ino;
error = -EINVAL;
inode = proc_get_inode(dir->i_sb, ino, de);
break;
@@ -631,11 +530,7 @@
static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
{
- unsigned int pid, c;
struct task_struct *p;
- const char *name;
- struct inode *inode;
- int len;
if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
extern unsigned long total_forks;
@@ -666,40 +561,7 @@
if (!proc_lookup(dir, dentry))
return NULL;
- pid = 0;
- name = dentry->d_name.name;
- len = dentry->d_name.len;
- while (len-- > 0) {
- c = *name - '0';
- name++;
- if (c > 9) {
- pid = 0;
- break;
- }
- pid *= 10;
- pid += c;
- if (!pid)
- break;
- if (pid & 0xffff0000) {
- pid = 0;
- break;
- }
- }
- 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)
- return ERR_PTR(-EINVAL);
- inode->i_flags|=S_IMMUTABLE;
- }
-
- dentry->d_op = &proc_dentry_operations;
- d_add(dentry, inode);
- return NULL;
+ return proc_pid_lookup(dir, dentry);
}
/*
@@ -738,7 +600,6 @@
filp->f_pos++;
/* fall through */
default:
- ino &= ~0xffff;
de = de->subdir;
i -= 2;
for (;;) {
@@ -751,7 +612,7 @@
}
do {
- if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0)
+ if (filldir(dirent, de->name, de->namelen, filp->f_pos, de->low_ino) < 0)
return 0;
filp->f_pos++;
de = de->next;
@@ -760,69 +621,19 @@
return 1;
}
-#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(int index, unsigned int *pids)
-{
- struct task_struct *p;
- int nr_pids = 0;
-
- index -= FIRST_PROCESS_ENTRY;
- read_lock(&tasklist_lock);
- for_each_task(p) {
- int pid = p->pid;
- if (!pid)
- continue;
- if (--index >= 0)
- 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)
{
- 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 = nr = FIRST_PROCESS_ENTRY;
+ filp->f_pos = FIRST_PROCESS_ENTRY;
}
- nr_pids = get_pid_list(nr, pid_array);
-
- for (i = 0; i < nr_pids; i++) {
- int pid = pid_array[i];
- ino_t ino = (pid << 16) + PROC_PID_INO;
- unsigned long j = PROC_NUMBUF;
-
- do {
- j--;
- buf[j] = '0' + (pid % 10);
- pid /= 10;
- } while (pid);
-
- if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino) < 0)
- break;
- filp->f_pos++;
- }
- return 0;
+ return proc_pid_readdir(filp, dirent, filldir);
}
static int proc_unlink(struct inode *dir, struct dentry *dentry)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)