summaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-11-28 03:58:46 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-11-28 03:58:46 +0000
commitb63ad0882a16a5d28003e57f2b0b81dee3fb322b (patch)
tree0a343ce219e2b8b38a5d702d66032c57b83d9720 /fs/proc
parenta9d7bff9a84dba79609a0002e5321b74c4d64c64 (diff)
Merge with 2.4.0-test11.
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/base.c32
-rw-r--r--fs/proc/generic.c10
-rw-r--r--fs/proc/inode.c15
-rw-r--r--fs/proc/proc_misc.c174
-rw-r--r--fs/proc/root.c14
6 files changed, 81 insertions, 166 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index d12a577fa..e98061fa8 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -372,7 +372,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
task->start_time,
vsize,
mm ? mm->rss : 0, /* you might want to shift this left 3 */
- task->rlim ? task->rlim[RLIMIT_RSS].rlim_cur : 0,
+ task->rlim[RLIMIT_RSS].rlim_cur,
mm ? mm->start_code : 0,
mm ? mm->end_code : 0,
mm ? mm->start_stack : 0,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a1f7efe0f..c1a960c5d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -207,15 +207,12 @@ static int standard_permission(struct inode *inode, int mask)
return -EACCES;
}
-static int proc_permission(struct inode *inode, int mask)
+static int proc_check_root(struct inode *inode)
{
struct dentry *de, *base, *root;
struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
int res = 0;
- if (standard_permission(inode, mask) != 0)
- return -EACCES;
-
if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
return -ENOENT;
read_lock(&current->fs->lock);
@@ -250,6 +247,13 @@ out:
goto exit;
}
+static int proc_permission(struct inode *inode, int mask)
+{
+ if (standard_permission(inode, mask) != 0)
+ return -EACCES;
+ return proc_check_root(inode);
+}
+
static ssize_t pid_maps_read(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
@@ -403,12 +407,14 @@ static struct inode_operations proc_mem_inode_operations = {
static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
- int error;
+ int error = -EACCES;
/* We don't need a base pointer in the /proc filesystem */
path_release(nd);
- error = proc_permission(inode, MAY_EXEC);
+ if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
+ goto out;
+ error = proc_check_root(inode);
if (error)
goto out;
@@ -441,12 +447,14 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen)
{
- int error;
+ int error = -EACCES;
struct inode *inode = dentry->d_inode;
struct dentry *de;
struct vfsmount *mnt = NULL;
- error = proc_permission(inode, MAY_EXEC);
+ if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
+ goto out;
+ error = proc_check_root(inode);
if (error)
goto out;
@@ -618,14 +626,12 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
/* We need a new inode */
- inode = get_empty_inode();
+ inode = new_inode(sb);
if (!inode)
goto out;
/* Common stuff */
- inode->i_sb = sb;
- inode->i_dev = sb->s_dev;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(task->pid, ino);
@@ -910,11 +916,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
name = dentry->d_name.name;
len = dentry->d_name.len;
if (len == 4 && !memcmp(name, "self", 4)) {
- inode = get_empty_inode();
+ inode = new_inode(dir->i_sb);
if (!inode)
return ERR_PTR(-ENOMEM);
- inode->i_sb = dir->i_sb;
- inode->i_dev = dir->i_sb->s_dev;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(0, PROC_PID_INO);
inode->u.proc_i.file = NULL;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 0dd6e6063..e58b04e02 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -215,7 +215,7 @@ static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
static struct inode_operations proc_link_inode_operations = {
readlink: proc_readlink,
- follow_link: proc_follow_link
+ follow_link: proc_follow_link,
};
/*
@@ -396,8 +396,6 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
if (dentry->d_op != &proc_dentry_operations)
continue;
inode = dentry->d_inode;
- if (!inode)
- continue;
if (inode->u.generic_ip != de)
continue;
fops_put(filp->f_op);
@@ -573,12 +571,12 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
(void *) proc_alloc_map);
proc_kill_inodes(de);
de->nlink = 0;
- de->deleted = 1;
- if (!de->count)
+ if (!atomic_read(&de->count))
free_proc_entry(de);
else {
+ de->deleted = 1;
printk("remove_proc_entry: %s/%s busy, count=%d\n",
- parent->name, de->name, de->count);
+ parent->name, de->name, atomic_read(&de->count));
}
break;
}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 7b571398a..3453bf88b 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -25,7 +25,7 @@ extern void free_proc_entry(struct proc_dir_entry *);
struct proc_dir_entry * de_get(struct proc_dir_entry *de)
{
if (de)
- de->count++;
+ atomic_inc(&de->count);
return de;
}
@@ -34,20 +34,21 @@ struct proc_dir_entry * de_get(struct proc_dir_entry *de)
*/
void de_put(struct proc_dir_entry *de)
{
- if (de) {
- lock_kernel(); /* FIXME: count should be atomic_t */
- if (!de->count) {
+ if (de) {
+ lock_kernel();
+ if (!atomic_read(&de->count)) {
printk("de_put: entry %s already free!\n", de->name);
+ unlock_kernel();
return;
}
- if (!--de->count) {
+ if (atomic_dec_and_test(&de->count)) {
if (de->deleted) {
printk("de_put: deferred delete of %s\n",
de->name);
free_proc_entry(de);
}
- }
+ }
unlock_kernel();
}
}
@@ -139,7 +140,7 @@ struct inode * proc_get_inode(struct super_block * sb, int ino,
#if 1
/* shouldn't ever happen */
if (de && de->deleted)
-printk("proc_iget: using deleted entry %s, count=%d\n", de->name, de->count);
+printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&de->count));
#endif
inode = iget(sb, ino);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 5e94c6aa5..d24f65b50 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -9,6 +9,10 @@
* there. I took this into a separate file and switched the thing to generic
* proc_file_inode_operations, leaving in array.c only per-process stuff.
* Inumbers allocation made dynamic (via create_proc_entry()). AV, May 1999.
+ *
+ * Changes:
+ * Fulton Green : Encapsulated position metric calculations.
+ * <kernel@FultonGreen.com>
*/
#include <linux/types.h>
@@ -68,6 +72,17 @@ extern int get_swaparea_info (char *);
extern int get_ds1286_status(char *);
#endif
+static int proc_calc_metrics(char *page, char **start, off_t off,
+ int count, int *eof, int len)
+{
+ if (len <= off+count) *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len>count) len = count;
+ if (len<0) len = 0;
+ return len;
+}
+
static int loadavg_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -82,12 +97,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
LOAD_INT(b), LOAD_FRAC(b),
LOAD_INT(c), LOAD_FRAC(c),
nr_running, nr_threads, last_pid);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int uptime_read_proc(char *page, char **start, off_t off,
@@ -122,12 +132,7 @@ static int uptime_read_proc(char *page, char **start, off_t off,
idle / HZ,
idle % HZ);
#endif
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int meminfo_read_proc(char *page, char **start, off_t off,
@@ -187,12 +192,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
K(i.totalswap),
K(i.freeswap));
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
#undef B
#undef K
}
@@ -205,20 +205,14 @@ static int version_read_proc(char *page, char **start, off_t off,
strcpy(page, linux_banner);
len = strlen(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int cpuinfo_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_cpuinfo(page, start, off, count);
- if (len < count) *eof = 1;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#ifdef CONFIG_PROC_HARDWARE
@@ -226,12 +220,7 @@ static int hardware_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_hardware_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -240,12 +229,7 @@ static int stram_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_stram_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -254,12 +238,7 @@ static int malloc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_malloc(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -268,12 +247,7 @@ static int modules_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_module_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int ksyms_read_proc(char *page, char **start, off_t off,
@@ -356,24 +330,14 @@ static int kstat_read_proc(char *page, char **start, off_t off,
xtime.tv_sec - jif / HZ,
total_forks);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int devices_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_device_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int partitions_read_proc(char *page, char **start, off_t off,
@@ -389,12 +353,7 @@ static int interrupts_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_irq_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -402,36 +361,21 @@ static int filesystems_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_filesystem_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int dma_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_dma_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int ioports_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_ioport_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int cmdline_read_proc(char *page, char **start, off_t off,
@@ -442,12 +386,7 @@ static int cmdline_read_proc(char *page, char **start, off_t off,
len = sprintf(page, "%s\n", saved_command_line);
len = strlen(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#ifdef CONFIG_SGI_DS1286
@@ -455,12 +394,7 @@ static int ds1286_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_ds1286_status(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
#endif
@@ -479,48 +413,28 @@ static int mounts_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_filesystem_info(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int execdomains_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_exec_domain_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int swaps_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_swaparea_info(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
static int memory_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = get_mem_list(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ return proc_calc_metrics(page, start, off, count, eof, len);
}
/*
@@ -631,9 +545,9 @@ void __init proc_misc_init(void)
{"swaps", swaps_read_proc},
{"iomem", memory_read_proc},
{"execdomains", execdomains_read_proc},
- {NULL,NULL}
+ {NULL,}
};
- for(p=simple_ones;p->name;p++)
+ for (p = simple_ones; p->name; p++)
create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
/* And now for trickier ones */
@@ -661,12 +575,8 @@ void __init proc_misc_init(void)
entry->proc_fops = &ppc_htab_operations;
}
#endif
- {
- struct proc_dir_entry *res = create_proc_entry("slabinfo",
- S_IWUSR | S_IRUGO, NULL);
- if (res) {
- res->read_proc = slabinfo_read_proc;
- res->write_proc = slabinfo_write_proc;
- }
- }
+ entry = create_proc_read_entry("slabinfo", S_IWUSR | S_IRUGO, NULL,
+ slabinfo_read_proc, NULL);
+ if (entry)
+ entry->write_proc = slabinfo_write_proc;
}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 075a5843d..cae861960 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -96,10 +96,12 @@ static struct inode_operations proc_root_inode_operations = {
* This is the root "inode" in the /proc tree..
*/
struct proc_dir_entry proc_root = {
- PROC_ROOT_INO, 5, "/proc",
- S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
- 0, &proc_root_inode_operations, &proc_root_operations,
- NULL, NULL,
- NULL,
- &proc_root, NULL
+ low_ino: PROC_ROOT_INO,
+ namelen: 5,
+ name: "/proc",
+ mode: S_IFDIR | S_IRUGO | S_IXUGO,
+ nlink: 2,
+ proc_iops: &proc_root_inode_operations,
+ proc_fops: &proc_root_operations,
+ parent: &proc_root,
};