diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-11-28 03:58:46 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-11-28 03:58:46 +0000 |
commit | b63ad0882a16a5d28003e57f2b0b81dee3fb322b (patch) | |
tree | 0a343ce219e2b8b38a5d702d66032c57b83d9720 /fs/proc | |
parent | a9d7bff9a84dba79609a0002e5321b74c4d64c64 (diff) |
Merge with 2.4.0-test11.
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/array.c | 2 | ||||
-rw-r--r-- | fs/proc/base.c | 32 | ||||
-rw-r--r-- | fs/proc/generic.c | 10 | ||||
-rw-r--r-- | fs/proc/inode.c | 15 | ||||
-rw-r--r-- | fs/proc/proc_misc.c | 174 | ||||
-rw-r--r-- | fs/proc/root.c | 14 |
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(¤t->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, }; |