aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 15:04:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 15:04:37 -0400
commit88ed86fee6651033de9b7038dac7869a9f19775a (patch)
tree38b638d2e7cba110ec271275738f221feb7e0a37 /fs
parent3856d30ded1fe43c6657927ebad402d25cd128f4 (diff)
parent59c7572e82d69483a66eaa67b46548baeb69ecf4 (diff)
Merge branch 'proc' of git://git.kernel.org/pub/scm/linux/kernel/git/adobriyan/proc
* 'proc' of git://git.kernel.org/pub/scm/linux/kernel/git/adobriyan/proc: (35 commits) proc: remove fs/proc/proc_misc.c proc: move /proc/vmcore creation to fs/proc/vmcore.c proc: move pagecount stuff to fs/proc/page.c proc: move all /proc/kcore stuff to fs/proc/kcore.c proc: move /proc/schedstat boilerplate to kernel/sched_stats.h proc: move /proc/modules boilerplate to kernel/module.c proc: move /proc/diskstats boilerplate to block/genhd.c proc: move /proc/zoneinfo boilerplate to mm/vmstat.c proc: move /proc/vmstat boilerplate to mm/vmstat.c proc: move /proc/pagetypeinfo boilerplate to mm/vmstat.c proc: move /proc/buddyinfo boilerplate to mm/vmstat.c proc: move /proc/vmallocinfo to mm/vmalloc.c proc: move /proc/slabinfo boilerplate to mm/slub.c, mm/slab.c proc: move /proc/slab_allocators boilerplate to mm/slab.c proc: move /proc/interrupts boilerplate code to fs/proc/interrupts.c proc: move /proc/stat to fs/proc/stat.c proc: move rest of /proc/partitions code to block/genhd.c proc: move /proc/cpuinfo code to fs/proc/cpuinfo.c proc: move /proc/devices code to fs/proc/devices.c proc: move rest of /proc/locks to fs/locks.c ...
Diffstat (limited to 'fs')
-rw-r--r--fs/filesystems.c39
-rw-r--r--fs/locks.c22
-rw-r--r--fs/proc/Makefile13
-rw-r--r--fs/proc/cmdline.c29
-rw-r--r--fs/proc/cpuinfo.c24
-rw-r--r--fs/proc/devices.c70
-rw-r--r--fs/proc/generic.c3
-rw-r--r--fs/proc/inode.c3
-rw-r--r--fs/proc/internal.h3
-rw-r--r--fs/proc/interrupts.c53
-rw-r--r--fs/proc/kcore.c14
-rw-r--r--fs/proc/kmsg.c12
-rw-r--r--fs/proc/loadavg.c51
-rw-r--r--fs/proc/meminfo.c168
-rw-r--r--fs/proc/page.c147
-rw-r--r--fs/proc/proc_devtree.c3
-rw-r--r--fs/proc/proc_misc.c933
-rw-r--r--fs/proc/proc_sysctl.c4
-rw-r--r--fs/proc/root.c8
-rw-r--r--fs/proc/stat.c153
-rw-r--r--fs/proc/task_mmu.c25
-rw-r--r--fs/proc/uptime.c43
-rw-r--r--fs/proc/version.c34
-rw-r--r--fs/proc/vmcore.c6
24 files changed, 895 insertions, 965 deletions
diff --git a/fs/filesystems.c b/fs/filesystems.c
index f37f87262837..d0e20ced62dd 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -8,6 +8,8 @@
8 8
9#include <linux/syscalls.h> 9#include <linux/syscalls.h>
10#include <linux/fs.h> 10#include <linux/fs.h>
11#include <linux/proc_fs.h>
12#include <linux/seq_file.h>
11#include <linux/slab.h> 13#include <linux/slab.h>
12#include <linux/kmod.h> 14#include <linux/kmod.h>
13#include <linux/init.h> 15#include <linux/init.h>
@@ -214,6 +216,43 @@ int get_filesystem_list(char * buf)
214 return len; 216 return len;
215} 217}
216 218
219#ifdef CONFIG_PROC_FS
220static int filesystems_proc_show(struct seq_file *m, void *v)
221{
222 struct file_system_type * tmp;
223
224 read_lock(&file_systems_lock);
225 tmp = file_systems;
226 while (tmp) {
227 seq_printf(m, "%s\t%s\n",
228 (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
229 tmp->name);
230 tmp = tmp->next;
231 }
232 read_unlock(&file_systems_lock);
233 return 0;
234}
235
236static int filesystems_proc_open(struct inode *inode, struct file *file)
237{
238 return single_open(file, filesystems_proc_show, NULL);
239}
240
241static const struct file_operations filesystems_proc_fops = {
242 .open = filesystems_proc_open,
243 .read = seq_read,
244 .llseek = seq_lseek,
245 .release = single_release,
246};
247
248static int __init proc_filesystems_init(void)
249{
250 proc_create("filesystems", 0, NULL, &filesystems_proc_fops);
251 return 0;
252}
253module_init(proc_filesystems_init);
254#endif
255
217struct file_system_type *get_fs_type(const char *name) 256struct file_system_type *get_fs_type(const char *name)
218{ 257{
219 struct file_system_type *fs; 258 struct file_system_type *fs;
diff --git a/fs/locks.c b/fs/locks.c
index 20457486d6b2..09062e3ff104 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2079,6 +2079,7 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
2079EXPORT_SYMBOL_GPL(vfs_cancel_lock); 2079EXPORT_SYMBOL_GPL(vfs_cancel_lock);
2080 2080
2081#ifdef CONFIG_PROC_FS 2081#ifdef CONFIG_PROC_FS
2082#include <linux/proc_fs.h>
2082#include <linux/seq_file.h> 2083#include <linux/seq_file.h>
2083 2084
2084static void lock_get_status(struct seq_file *f, struct file_lock *fl, 2085static void lock_get_status(struct seq_file *f, struct file_lock *fl,
@@ -2184,12 +2185,31 @@ static void locks_stop(struct seq_file *f, void *v)
2184 unlock_kernel(); 2185 unlock_kernel();
2185} 2186}
2186 2187
2187struct seq_operations locks_seq_operations = { 2188static const struct seq_operations locks_seq_operations = {
2188 .start = locks_start, 2189 .start = locks_start,
2189 .next = locks_next, 2190 .next = locks_next,
2190 .stop = locks_stop, 2191 .stop = locks_stop,
2191 .show = locks_show, 2192 .show = locks_show,
2192}; 2193};
2194
2195static int locks_open(struct inode *inode, struct file *filp)
2196{
2197 return seq_open(filp, &locks_seq_operations);
2198}
2199
2200static const struct file_operations proc_locks_operations = {
2201 .open = locks_open,
2202 .read = seq_read,
2203 .llseek = seq_lseek,
2204 .release = seq_release,
2205};
2206
2207static int __init proc_locks_init(void)
2208{
2209 proc_create("locks", 0, NULL, &proc_locks_operations);
2210 return 0;
2211}
2212module_init(proc_locks_init);
2193#endif 2213#endif
2194 2214
2195/** 2215/**
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index ebaba0213546..63d965193b22 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,11 +8,20 @@ proc-y := nommu.o task_nommu.o
8proc-$(CONFIG_MMU) := mmu.o task_mmu.o 8proc-$(CONFIG_MMU) := mmu.o task_mmu.o
9 9
10proc-y += inode.o root.o base.o generic.o array.o \ 10proc-y += inode.o root.o base.o generic.o array.o \
11 proc_tty.o proc_misc.o 11 proc_tty.o
12 12proc-y += cmdline.o
13proc-y += cpuinfo.o
14proc-y += devices.o
15proc-y += interrupts.o
16proc-y += loadavg.o
17proc-y += meminfo.o
18proc-y += stat.o
19proc-y += uptime.o
20proc-y += version.o
13proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o 21proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o
14proc-$(CONFIG_NET) += proc_net.o 22proc-$(CONFIG_NET) += proc_net.o
15proc-$(CONFIG_PROC_KCORE) += kcore.o 23proc-$(CONFIG_PROC_KCORE) += kcore.o
16proc-$(CONFIG_PROC_VMCORE) += vmcore.o 24proc-$(CONFIG_PROC_VMCORE) += vmcore.o
17proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o 25proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
18proc-$(CONFIG_PRINTK) += kmsg.o 26proc-$(CONFIG_PRINTK) += kmsg.o
27proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o
diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c
new file mode 100644
index 000000000000..82676e3fcd1d
--- /dev/null
+++ b/fs/proc/cmdline.c
@@ -0,0 +1,29 @@
1#include <linux/fs.h>
2#include <linux/init.h>
3#include <linux/proc_fs.h>
4#include <linux/seq_file.h>
5
6static int cmdline_proc_show(struct seq_file *m, void *v)
7{
8 seq_printf(m, "%s\n", saved_command_line);
9 return 0;
10}
11
12static int cmdline_proc_open(struct inode *inode, struct file *file)
13{
14 return single_open(file, cmdline_proc_show, NULL);
15}
16
17static const struct file_operations cmdline_proc_fops = {
18 .open = cmdline_proc_open,
19 .read = seq_read,
20 .llseek = seq_lseek,
21 .release = single_release,
22};
23
24static int __init proc_cmdline_init(void)
25{
26 proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
27 return 0;
28}
29module_init(proc_cmdline_init);
diff --git a/fs/proc/cpuinfo.c b/fs/proc/cpuinfo.c
new file mode 100644
index 000000000000..5a1e539a234b
--- /dev/null
+++ b/fs/proc/cpuinfo.c
@@ -0,0 +1,24 @@
1#include <linux/fs.h>
2#include <linux/init.h>
3#include <linux/proc_fs.h>
4#include <linux/seq_file.h>
5
6extern const struct seq_operations cpuinfo_op;
7static int cpuinfo_open(struct inode *inode, struct file *file)
8{
9 return seq_open(file, &cpuinfo_op);
10}
11
12static const struct file_operations proc_cpuinfo_operations = {
13 .open = cpuinfo_open,
14 .read = seq_read,
15 .llseek = seq_lseek,
16 .release = seq_release,
17};
18
19static int __init proc_cpuinfo_init(void)
20{
21 proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
22 return 0;
23}
24module_init(proc_cpuinfo_init);
diff --git a/fs/proc/devices.c b/fs/proc/devices.c
new file mode 100644
index 000000000000..59ee7da959c9
--- /dev/null
+++ b/fs/proc/devices.c
@@ -0,0 +1,70 @@
1#include <linux/fs.h>
2#include <linux/init.h>
3#include <linux/proc_fs.h>
4#include <linux/seq_file.h>
5
6static int devinfo_show(struct seq_file *f, void *v)
7{
8 int i = *(loff_t *) v;
9
10 if (i < CHRDEV_MAJOR_HASH_SIZE) {
11 if (i == 0)
12 seq_printf(f, "Character devices:\n");
13 chrdev_show(f, i);
14 }
15#ifdef CONFIG_BLOCK
16 else {
17 i -= CHRDEV_MAJOR_HASH_SIZE;
18 if (i == 0)
19 seq_printf(f, "\nBlock devices:\n");
20 blkdev_show(f, i);
21 }
22#endif
23 return 0;
24}
25
26static void *devinfo_start(struct seq_file *f, loff_t *pos)
27{
28 if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
29 return pos;
30 return NULL;
31}
32
33static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
34{
35 (*pos)++;
36 if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
37 return NULL;
38 return pos;
39}
40
41static void devinfo_stop(struct seq_file *f, void *v)
42{
43 /* Nothing to do */
44}
45
46static const struct seq_operations devinfo_ops = {
47 .start = devinfo_start,
48 .next = devinfo_next,
49 .stop = devinfo_stop,
50 .show = devinfo_show
51};
52
53static int devinfo_open(struct inode *inode, struct file *filp)
54{
55 return seq_open(filp, &devinfo_ops);
56}
57
58static const struct file_operations proc_devinfo_operations = {
59 .open = devinfo_open,
60 .read = seq_read,
61 .llseek = seq_lseek,
62 .release = seq_release,
63};
64
65static int __init proc_devices_init(void)
66{
67 proc_create("devices", 0, NULL, &proc_devinfo_operations);
68 return 0;
69}
70module_init(proc_devices_init);
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 7821589a17d5..60a359b35582 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -547,9 +547,8 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
547 547
548 for (tmp = dir->subdir; tmp; tmp = tmp->next) 548 for (tmp = dir->subdir; tmp; tmp = tmp->next)
549 if (strcmp(tmp->name, dp->name) == 0) { 549 if (strcmp(tmp->name, dp->name) == 0) {
550 printk(KERN_WARNING "proc_dir_entry '%s/%s' already registered\n", 550 WARN(1, KERN_WARNING "proc_dir_entry '%s/%s' already registered\n",
551 dir->name, dp->name); 551 dir->name, dp->name);
552 dump_stack();
553 break; 552 break;
554 } 553 }
555 554
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index c6b4fa7e3b49..2543fd00c658 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -106,14 +106,13 @@ static void init_once(void *foo)
106 inode_init_once(&ei->vfs_inode); 106 inode_init_once(&ei->vfs_inode);
107} 107}
108 108
109int __init proc_init_inodecache(void) 109void __init proc_init_inodecache(void)
110{ 110{
111 proc_inode_cachep = kmem_cache_create("proc_inode_cache", 111 proc_inode_cachep = kmem_cache_create("proc_inode_cache",
112 sizeof(struct proc_inode), 112 sizeof(struct proc_inode),
113 0, (SLAB_RECLAIM_ACCOUNT| 113 0, (SLAB_RECLAIM_ACCOUNT|
114 SLAB_MEM_SPREAD|SLAB_PANIC), 114 SLAB_MEM_SPREAD|SLAB_PANIC),
115 init_once); 115 init_once);
116 return 0;
117} 116}
118 117
119static const struct super_operations proc_sops = { 118static const struct super_operations proc_sops = {
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 3bfb7b8747b3..3e8aeb8b61ce 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -61,12 +61,11 @@ extern const struct file_operations proc_smaps_operations;
61extern const struct file_operations proc_clear_refs_operations; 61extern const struct file_operations proc_clear_refs_operations;
62extern const struct file_operations proc_pagemap_operations; 62extern const struct file_operations proc_pagemap_operations;
63extern const struct file_operations proc_net_operations; 63extern const struct file_operations proc_net_operations;
64extern const struct file_operations proc_kmsg_operations;
65extern const struct inode_operations proc_net_inode_operations; 64extern const struct inode_operations proc_net_inode_operations;
66 65
67void free_proc_entry(struct proc_dir_entry *de); 66void free_proc_entry(struct proc_dir_entry *de);
68 67
69int proc_init_inodecache(void); 68void proc_init_inodecache(void);
70 69
71static inline struct pid *proc_pid(struct inode *inode) 70static inline struct pid *proc_pid(struct inode *inode)
72{ 71{
diff --git a/fs/proc/interrupts.c b/fs/proc/interrupts.c
new file mode 100644
index 000000000000..05029c0e2f24
--- /dev/null
+++ b/fs/proc/interrupts.c
@@ -0,0 +1,53 @@
1#include <linux/fs.h>
2#include <linux/init.h>
3#include <linux/interrupt.h>
4#include <linux/irqnr.h>
5#include <linux/proc_fs.h>
6#include <linux/seq_file.h>
7
8/*
9 * /proc/interrupts
10 */
11static void *int_seq_start(struct seq_file *f, loff_t *pos)
12{
13 return (*pos <= nr_irqs) ? pos : NULL;
14}
15
16static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
17{
18 (*pos)++;
19 if (*pos > nr_irqs)
20 return NULL;
21 return pos;
22}
23
24static void int_seq_stop(struct seq_file *f, void *v)
25{
26 /* Nothing to do */
27}
28
29static const struct seq_operations int_seq_ops = {
30 .start = int_seq_start,
31 .next = int_seq_next,
32 .stop = int_seq_stop,
33 .show = show_interrupts
34};
35
36static int interrupts_open(struct inode *inode, struct file *filp)
37{
38 return seq_open(filp, &int_seq_ops);
39}
40
41static const struct file_operations proc_interrupts_operations = {
42 .open = interrupts_open,
43 .read = seq_read,
44 .llseek = seq_lseek,
45 .release = seq_release,
46};
47
48static int __init proc_interrupts_init(void)
49{
50 proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
51 return 0;
52}
53module_init(proc_interrupts_init);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index c2370c76fb71..59b43a068872 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -27,6 +27,8 @@
27#define ELF_CORE_EFLAGS 0 27#define ELF_CORE_EFLAGS 0
28#endif 28#endif
29 29
30static struct proc_dir_entry *proc_root_kcore;
31
30static int open_kcore(struct inode * inode, struct file * filp) 32static int open_kcore(struct inode * inode, struct file * filp)
31{ 33{
32 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; 34 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
@@ -34,7 +36,7 @@ static int open_kcore(struct inode * inode, struct file * filp)
34 36
35static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *); 37static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
36 38
37const struct file_operations proc_kcore_operations = { 39static const struct file_operations proc_kcore_operations = {
38 .read = read_kcore, 40 .read = read_kcore,
39 .open = open_kcore, 41 .open = open_kcore,
40}; 42};
@@ -399,3 +401,13 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
399 401
400 return acc; 402 return acc;
401} 403}
404
405static int __init proc_kcore_init(void)
406{
407 proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
408 if (proc_root_kcore)
409 proc_root_kcore->size =
410 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
411 return 0;
412}
413module_init(proc_kcore_init);
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 9fd5df3f40ce..7ca78346d3f0 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -10,13 +10,12 @@
10#include <linux/time.h> 10#include <linux/time.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/poll.h> 12#include <linux/poll.h>
13#include <linux/proc_fs.h>
13#include <linux/fs.h> 14#include <linux/fs.h>
14 15
15#include <asm/uaccess.h> 16#include <asm/uaccess.h>
16#include <asm/io.h> 17#include <asm/io.h>
17 18
18#include "internal.h"
19
20extern wait_queue_head_t log_wait; 19extern wait_queue_head_t log_wait;
21 20
22extern int do_syslog(int type, char __user *bug, int count); 21extern int do_syslog(int type, char __user *bug, int count);
@@ -49,9 +48,16 @@ static unsigned int kmsg_poll(struct file *file, poll_table *wait)
49} 48}
50 49
51 50
52const struct file_operations proc_kmsg_operations = { 51static const struct file_operations proc_kmsg_operations = {
53 .read = kmsg_read, 52 .read = kmsg_read,
54 .poll = kmsg_poll, 53 .poll = kmsg_poll,
55 .open = kmsg_open, 54 .open = kmsg_open,
56 .release = kmsg_release, 55 .release = kmsg_release,
57}; 56};
57
58static int __init proc_kmsg_init(void)
59{
60 proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
61 return 0;
62}
63module_init(proc_kmsg_init);
diff --git a/fs/proc/loadavg.c b/fs/proc/loadavg.c
new file mode 100644
index 000000000000..9bca39cf99ee
--- /dev/null
+++ b/fs/proc/loadavg.c
@@ -0,0 +1,51 @@
1#include <linux/fs.h>
2#include <linux/init.h>
3#include <linux/pid_namespace.h>
4#include <linux/proc_fs.h>
5#include <linux/sched.h>
6#include <linux/seq_file.h>
7#include <linux/seqlock.h>
8#include <linux/time.h>
9
10#define LOAD_INT(x) ((x) >> FSHIFT)
11#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
12
13static int loadavg_proc_show(struct seq_file *m, void *v)
14{
15 int a, b, c;
16 unsigned long seq;
17
18 do {
19 seq = read_seqbegin(&xtime_lock);
20 a = avenrun[0] + (FIXED_1/200);
21 b = avenrun[1] + (FIXED_1/200);
22 c = avenrun[2] + (FIXED_1/200);
23 } while (read_seqretry(&xtime_lock, seq));
24
25 seq_printf(m, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
26 LOAD_INT(a), LOAD_FRAC(a),
27 LOAD_INT(b), LOAD_FRAC(b),
28 LOAD_INT(c), LOAD_FRAC(c),
29 nr_running(), nr_threads,
30 task_active_pid_ns(current)->last_pid);
31 return 0;
32}
33
34static int loadavg_proc_open(struct inode *inode, struct file *file)
35{
36 return single_open(file, loadavg_proc_show, NULL);
37}
38
39static const struct file_operations loadavg_proc_fops = {
40 .open = loadavg_proc_open,
41 .read = seq_read,
42 .llseek = seq_lseek,
43 .release = single_release,
44};
45
46static int __init proc_loadavg_init(void)
47{
48 proc_create("loadavg", 0, NULL, &loadavg_proc_fops);
49 return 0;
50}
51module_init(proc_loadavg_init);
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
new file mode 100644
index 000000000000..b1675c4e66da
--- /dev/null
+++ b/fs/proc/meminfo.c
@@ -0,0 +1,168 @@
1#include <linux/fs.h>
2#include <linux/hugetlb.h>
3#include <linux/init.h>
4#include <linux/kernel.h>
5#include <linux/mm.h>
6#include <linux/mman.h>
7#include <linux/mmzone.h>
8#include <linux/proc_fs.h>
9#include <linux/quicklist.h>
10#include <linux/seq_file.h>
11#include <linux/swap.h>
12#include <linux/vmstat.h>
13#include <asm/atomic.h>
14#include <asm/page.h>
15#include <asm/pgtable.h>
16#include "internal.h"
17
18void __attribute__((weak)) arch_report_meminfo(struct seq_file *m)
19{
20}
21
22static int meminfo_proc_show(struct seq_file *m, void *v)
23{
24 struct sysinfo i;
25 unsigned long committed;
26 unsigned long allowed;
27 struct vmalloc_info vmi;
28 long cached;
29 unsigned long pages[NR_LRU_LISTS];
30 int lru;
31
32/*
33 * display in kilobytes.
34 */
35#define K(x) ((x) << (PAGE_SHIFT - 10))
36 si_meminfo(&i);
37 si_swapinfo(&i);
38 committed = atomic_long_read(&vm_committed_space);
39 allowed = ((totalram_pages - hugetlb_total_pages())
40 * sysctl_overcommit_ratio / 100) + total_swap_pages;
41
42 cached = global_page_state(NR_FILE_PAGES) -
43 total_swapcache_pages - i.bufferram;
44 if (cached < 0)
45 cached = 0;
46
47 get_vmalloc_info(&vmi);
48
49 for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
50 pages[lru] = global_page_state(NR_LRU_BASE + lru);
51
52 /*
53 * Tagged format, for easy grepping and expansion.
54 */
55 seq_printf(m,
56 "MemTotal: %8lu kB\n"
57 "MemFree: %8lu kB\n"
58 "Buffers: %8lu kB\n"
59 "Cached: %8lu kB\n"
60 "SwapCached: %8lu kB\n"
61 "Active: %8lu kB\n"
62 "Inactive: %8lu kB\n"
63 "Active(anon): %8lu kB\n"
64 "Inactive(anon): %8lu kB\n"
65 "Active(file): %8lu kB\n"
66 "Inactive(file): %8lu kB\n"
67#ifdef CONFIG_UNEVICTABLE_LRU
68 "Unevictable: %8lu kB\n"
69 "Mlocked: %8lu kB\n"
70#endif
71#ifdef CONFIG_HIGHMEM
72 "HighTotal: %8lu kB\n"
73 "HighFree: %8lu kB\n"
74 "LowTotal: %8lu kB\n"
75 "LowFree: %8lu kB\n"
76#endif
77 "SwapTotal: %8lu kB\n"
78 "SwapFree: %8lu kB\n"
79 "Dirty: %8lu kB\n"
80 "Writeback: %8lu kB\n"
81 "AnonPages: %8lu kB\n"
82 "Mapped: %8lu kB\n"
83 "Slab: %8lu kB\n"
84 "SReclaimable: %8lu kB\n"
85 "SUnreclaim: %8lu kB\n"
86 "PageTables: %8lu kB\n"
87#ifdef CONFIG_QUICKLIST
88 "Quicklists: %8lu kB\n"
89#endif
90 "NFS_Unstable: %8lu kB\n"
91 "Bounce: %8lu kB\n"
92 "WritebackTmp: %8lu kB\n"
93 "CommitLimit: %8lu kB\n"
94 "Committed_AS: %8lu kB\n"
95 "VmallocTotal: %8lu kB\n"
96 "VmallocUsed: %8lu kB\n"
97 "VmallocChunk: %8lu kB\n",
98 K(i.totalram),
99 K(i.freeram),
100 K(i.bufferram),
101 K(cached),
102 K(total_swapcache_pages),
103 K(pages[LRU_ACTIVE_ANON] + pages[LRU_ACTIVE_FILE]),
104 K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]),
105 K(pages[LRU_ACTIVE_ANON]),
106 K(pages[LRU_INACTIVE_ANON]),
107 K(pages[LRU_ACTIVE_FILE]),
108 K(pages[LRU_INACTIVE_FILE]),
109#ifdef CONFIG_UNEVICTABLE_LRU
110 K(pages[LRU_UNEVICTABLE]),
111 K(global_page_state(NR_MLOCK)),
112#endif
113#ifdef CONFIG_HIGHMEM
114 K(i.totalhigh),
115 K(i.freehigh),
116 K(i.totalram-i.totalhigh),
117 K(i.freeram-i.freehigh),
118#endif
119 K(i.totalswap),
120 K(i.freeswap),
121 K(global_page_state(NR_FILE_DIRTY)),
122 K(global_page_state(NR_WRITEBACK)),
123 K(global_page_state(NR_ANON_PAGES)),
124 K(global_page_state(NR_FILE_MAPPED)),
125 K(global_page_state(NR_SLAB_RECLAIMABLE) +
126 global_page_state(NR_SLAB_UNRECLAIMABLE)),
127 K(global_page_state(NR_SLAB_RECLAIMABLE)),
128 K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
129 K(global_page_state(NR_PAGETABLE)),
130#ifdef CONFIG_QUICKLIST
131 K(quicklist_total_size()),
132#endif
133 K(global_page_state(NR_UNSTABLE_NFS)),
134 K(global_page_state(NR_BOUNCE)),
135 K(global_page_state(NR_WRITEBACK_TEMP)),
136 K(allowed),
137 K(committed),
138 (unsigned long)VMALLOC_TOTAL >> 10,
139 vmi.used >> 10,
140 vmi.largest_chunk >> 10
141 );
142
143 hugetlb_report_meminfo(m);
144
145 arch_report_meminfo(m);
146
147 return 0;
148#undef K
149}
150
151static int meminfo_proc_open(struct inode *inode, struct file *file)
152{
153 return single_open(file, meminfo_proc_show, NULL);
154}
155
156static const struct file_operations meminfo_proc_fops = {
157 .open = meminfo_proc_open,
158 .read = seq_read,
159 .llseek = seq_lseek,
160 .release = single_release,
161};
162
163static int __init proc_meminfo_init(void)
164{
165 proc_create("meminfo", 0, NULL, &meminfo_proc_fops);
166 return 0;
167}
168module_init(proc_meminfo_init);
diff --git a/fs/proc/page.c b/fs/proc/page.c
new file mode 100644
index 000000000000..767d95a6d1b1
--- /dev/null
+++ b/fs/proc/page.c
@@ -0,0 +1,147 @@
1#include <linux/bootmem.h>
2#include <linux/compiler.h>
3#include <linux/fs.h>
4#include <linux/init.h>
5#include <linux/mm.h>
6#include <linux/mmzone.h>
7#include <linux/proc_fs.h>
8#include <linux/seq_file.h>
9#include <asm/uaccess.h>
10#include "internal.h"
11
12#define KPMSIZE sizeof(u64)
13#define KPMMASK (KPMSIZE - 1)
14/* /proc/kpagecount - an array exposing page counts
15 *
16 * Each entry is a u64 representing the corresponding
17 * physical page count.
18 */
19static ssize_t kpagecount_read(struct file *file, char __user *buf,
20 size_t count, loff_t *ppos)
21{
22 u64 __user *out = (u64 __user *)buf;
23 struct page *ppage;
24 unsigned long src = *ppos;
25 unsigned long pfn;
26 ssize_t ret = 0;
27 u64 pcount;
28
29 pfn = src / KPMSIZE;
30 count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
31 if (src & KPMMASK || count & KPMMASK)
32 return -EINVAL;
33
34 while (count > 0) {
35 ppage = NULL;
36 if (pfn_valid(pfn))
37 ppage = pfn_to_page(pfn);
38 pfn++;
39 if (!ppage)
40 pcount = 0;
41 else
42 pcount = page_mapcount(ppage);
43
44 if (put_user(pcount, out++)) {
45 ret = -EFAULT;
46 break;
47 }
48
49 count -= KPMSIZE;
50 }
51
52 *ppos += (char __user *)out - buf;
53 if (!ret)
54 ret = (char __user *)out - buf;
55 return ret;
56}
57
58static const struct file_operations proc_kpagecount_operations = {
59 .llseek = mem_lseek,
60 .read = kpagecount_read,
61};
62
63/* /proc/kpageflags - an array exposing page flags
64 *
65 * Each entry is a u64 representing the corresponding
66 * physical page flags.
67 */
68
69/* These macros are used to decouple internal flags from exported ones */
70
71#define KPF_LOCKED 0
72#define KPF_ERROR 1
73#define KPF_REFERENCED 2
74#define KPF_UPTODATE 3
75#define KPF_DIRTY 4
76#define KPF_LRU 5
77#define KPF_ACTIVE 6
78#define KPF_SLAB 7
79#define KPF_WRITEBACK 8
80#define KPF_RECLAIM 9
81#define KPF_BUDDY 10
82
83#define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos)
84
85static ssize_t kpageflags_read(struct file *file, char __user *buf,
86 size_t count, loff_t *ppos)
87{
88 u64 __user *out = (u64 __user *)buf;
89 struct page *ppage;
90 unsigned long src = *ppos;
91 unsigned long pfn;
92 ssize_t ret = 0;
93 u64 kflags, uflags;
94
95 pfn = src / KPMSIZE;
96 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
97 if (src & KPMMASK || count & KPMMASK)
98 return -EINVAL;
99
100 while (count > 0) {
101 ppage = NULL;
102 if (pfn_valid(pfn))
103 ppage = pfn_to_page(pfn);
104 pfn++;
105 if (!ppage)
106 kflags = 0;
107 else
108 kflags = ppage->flags;
109
110 uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) |
111 kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
112 kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
113 kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
114 kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
115 kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
116 kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
117 kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
118 kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
119 kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
120 kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
121
122 if (put_user(uflags, out++)) {
123 ret = -EFAULT;
124 break;
125 }
126
127 count -= KPMSIZE;
128 }
129
130 *ppos += (char __user *)out - buf;
131 if (!ret)
132 ret = (char __user *)out - buf;
133 return ret;
134}
135
136static const struct file_operations proc_kpageflags_operations = {
137 .llseek = mem_lseek,
138 .read = kpageflags_read,
139};
140
141static int __init proc_page_init(void)
142{
143 proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
144 proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
145 return 0;
146}
147module_init(proc_page_init);
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index eca471bc8512..d777789b7a89 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -4,6 +4,7 @@
4 * Copyright 1997 Paul Mackerras 4 * Copyright 1997 Paul Mackerras
5 */ 5 */
6#include <linux/errno.h> 6#include <linux/errno.h>
7#include <linux/init.h>
7#include <linux/time.h> 8#include <linux/time.h>
8#include <linux/proc_fs.h> 9#include <linux/proc_fs.h>
9#include <linux/stat.h> 10#include <linux/stat.h>
@@ -214,7 +215,7 @@ void proc_device_tree_add_node(struct device_node *np,
214/* 215/*
215 * Called on initialization to set up the /proc/device-tree subtree 216 * Called on initialization to set up the /proc/device-tree subtree
216 */ 217 */
217void proc_device_tree_init(void) 218void __init proc_device_tree_init(void)
218{ 219{
219 struct device_node *root; 220 struct device_node *root;
220 if ( !have_of ) 221 if ( !have_of )
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
deleted file mode 100644
index 7ea52c79b2da..000000000000
--- a/fs/proc/proc_misc.c
+++ /dev/null
@@ -1,933 +0,0 @@
1/*
2 * linux/fs/proc/proc_misc.c
3 *
4 * linux/fs/proc/array.c
5 * Copyright (C) 1992 by Linus Torvalds
6 * based on ideas by Darren Senn
7 *
8 * This used to be the part of array.c. See the rest of history and credits
9 * there. I took this into a separate file and switched the thing to generic
10 * proc_file_inode_operations, leaving in array.c only per-process stuff.
11 * Inumbers allocation made dynamic (via create_proc_entry()). AV, May 1999.
12 *
13 * Changes:
14 * Fulton Green : Encapsulated position metric calculations.
15 * <kernel@FultonGreen.com>
16 */
17
18#include <linux/types.h>
19#include <linux/errno.h>
20#include <linux/time.h>
21#include <linux/kernel.h>
22#include <linux/kernel_stat.h>
23#include <linux/fs.h>
24#include <linux/tty.h>
25#include <linux/string.h>
26#include <linux/mman.h>
27#include <linux/quicklist.h>
28#include <linux/proc_fs.h>
29#include <linux/ioport.h>
30#include <linux/mm.h>
31#include <linux/mmzone.h>
32#include <linux/pagemap.h>
33#include <linux/irq.h>
34#include <linux/interrupt.h>
35#include <linux/swap.h>
36#include <linux/slab.h>
37#include <linux/genhd.h>
38#include <linux/smp.h>
39#include <linux/signal.h>
40#include <linux/module.h>
41#include <linux/init.h>
42#include <linux/seq_file.h>
43#include <linux/times.h>
44#include <linux/profile.h>
45#include <linux/utsname.h>
46#include <linux/blkdev.h>
47#include <linux/hugetlb.h>
48#include <linux/jiffies.h>
49#include <linux/vmalloc.h>
50#include <linux/crash_dump.h>
51#include <linux/pid_namespace.h>
52#include <linux/bootmem.h>
53#include <asm/uaccess.h>
54#include <asm/pgtable.h>
55#include <asm/io.h>
56#include <asm/tlb.h>
57#include <asm/div64.h>
58#include "internal.h"
59
60#define LOAD_INT(x) ((x) >> FSHIFT)
61#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
62/*
63 * Warning: stuff below (imported functions) assumes that its output will fit
64 * into one page. For some of those functions it may be wrong. Moreover, we
65 * have a way to deal with that gracefully. Right now I used straightforward
66 * wrappers, but this needs further analysis wrt potential overflows.
67 */
68extern int get_hardware_list(char *);
69extern int get_stram_list(char *);
70extern int get_exec_domain_list(char *);
71
72static int proc_calc_metrics(char *page, char **start, off_t off,
73 int count, int *eof, int len)
74{
75 if (len <= off+count) *eof = 1;
76 *start = page + off;
77 len -= off;
78 if (len>count) len = count;
79 if (len<0) len = 0;
80 return len;
81}
82
83static int loadavg_read_proc(char *page, char **start, off_t off,
84 int count, int *eof, void *data)
85{
86 int a, b, c;
87 int len;
88 unsigned long seq;
89
90 do {
91 seq = read_seqbegin(&xtime_lock);
92 a = avenrun[0] + (FIXED_1/200);
93 b = avenrun[1] + (FIXED_1/200);
94 c = avenrun[2] + (FIXED_1/200);
95 } while (read_seqretry(&xtime_lock, seq));
96
97 len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
98 LOAD_INT(a), LOAD_FRAC(a),
99 LOAD_INT(b), LOAD_FRAC(b),
100 LOAD_INT(c), LOAD_FRAC(c),
101 nr_running(), nr_threads,
102 task_active_pid_ns(current)->last_pid);
103 return proc_calc_metrics(page, start, off, count, eof, len);
104}
105
106static int uptime_read_proc(char *page, char **start, off_t off,
107 int count, int *eof, void *data)
108{
109 struct timespec uptime;
110 struct timespec idle;
111 int len;
112 cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
113
114 do_posix_clock_monotonic_gettime(&uptime);
115 monotonic_to_bootbased(&uptime);
116 cputime_to_timespec(idletime, &idle);
117 len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
118 (unsigned long) uptime.tv_sec,
119 (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
120 (unsigned long) idle.tv_sec,
121 (idle.tv_nsec / (NSEC_PER_SEC / 100)));
122
123 return proc_calc_metrics(page, start, off, count, eof, len);
124}
125
126int __attribute__((weak)) arch_report_meminfo(char *page)
127{
128 return 0;
129}
130
131static int meminfo_read_proc(char *page, char **start, off_t off,
132 int count, int *eof, void *data)
133{
134 struct sysinfo i;
135 int len;
136 unsigned long committed;
137 unsigned long allowed;
138 struct vmalloc_info vmi;
139 long cached;
140 unsigned long pages[NR_LRU_LISTS];
141 int lru;
142
143/*
144 * display in kilobytes.
145 */
146#define K(x) ((x) << (PAGE_SHIFT - 10))
147 si_meminfo(&i);
148 si_swapinfo(&i);
149 committed = atomic_long_read(&vm_committed_space);
150 allowed = ((totalram_pages - hugetlb_total_pages())
151 * sysctl_overcommit_ratio / 100) + total_swap_pages;
152
153 cached = global_page_state(NR_FILE_PAGES) -
154 total_swapcache_pages - i.bufferram;
155 if (cached < 0)
156 cached = 0;
157
158 get_vmalloc_info(&vmi);
159
160 for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
161 pages[lru] = global_page_state(NR_LRU_BASE + lru);
162
163 /*
164 * Tagged format, for easy grepping and expansion.
165 */
166 len = sprintf(page,
167 "MemTotal: %8lu kB\n"
168 "MemFree: %8lu kB\n"
169 "Buffers: %8lu kB\n"
170 "Cached: %8lu kB\n"
171 "SwapCached: %8lu kB\n"
172 "Active: %8lu kB\n"
173 "Inactive: %8lu kB\n"
174 "Active(anon): %8lu kB\n"
175 "Inactive(anon): %8lu kB\n"
176 "Active(file): %8lu kB\n"
177 "Inactive(file): %8lu kB\n"
178#ifdef CONFIG_UNEVICTABLE_LRU
179 "Unevictable: %8lu kB\n"
180 "Mlocked: %8lu kB\n"
181#endif
182#ifdef CONFIG_HIGHMEM
183 "HighTotal: %8lu kB\n"
184 "HighFree: %8lu kB\n"
185 "LowTotal: %8lu kB\n"
186 "LowFree: %8lu kB\n"
187#endif
188 "SwapTotal: %8lu kB\n"
189 "SwapFree: %8lu kB\n"
190 "Dirty: %8lu kB\n"
191 "Writeback: %8lu kB\n"
192 "AnonPages: %8lu kB\n"
193 "Mapped: %8lu kB\n"
194 "Slab: %8lu kB\n"
195 "SReclaimable: %8lu kB\n"
196 "SUnreclaim: %8lu kB\n"
197 "PageTables: %8lu kB\n"
198#ifdef CONFIG_QUICKLIST
199 "Quicklists: %8lu kB\n"
200#endif
201 "NFS_Unstable: %8lu kB\n"
202 "Bounce: %8lu kB\n"
203 "WritebackTmp: %8lu kB\n"
204 "CommitLimit: %8lu kB\n"
205 "Committed_AS: %8lu kB\n"
206 "VmallocTotal: %8lu kB\n"
207 "VmallocUsed: %8lu kB\n"
208 "VmallocChunk: %8lu kB\n",
209 K(i.totalram),
210 K(i.freeram),
211 K(i.bufferram),
212 K(cached),
213 K(total_swapcache_pages),
214 K(pages[LRU_ACTIVE_ANON] + pages[LRU_ACTIVE_FILE]),
215 K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]),
216 K(pages[LRU_ACTIVE_ANON]),
217 K(pages[LRU_INACTIVE_ANON]),
218 K(pages[LRU_ACTIVE_FILE]),
219 K(pages[LRU_INACTIVE_FILE]),
220#ifdef CONFIG_UNEVICTABLE_LRU
221 K(pages[LRU_UNEVICTABLE]),
222 K(global_page_state(NR_MLOCK)),
223#endif
224#ifdef CONFIG_HIGHMEM
225 K(i.totalhigh),
226 K(i.freehigh),
227 K(i.totalram-i.totalhigh),
228 K(i.freeram-i.freehigh),
229#endif
230 K(i.totalswap),
231 K(i.freeswap),
232 K(global_page_state(NR_FILE_DIRTY)),
233 K(global_page_state(NR_WRITEBACK)),
234 K(global_page_state(NR_ANON_PAGES)),
235 K(global_page_state(NR_FILE_MAPPED)),
236 K(global_page_state(NR_SLAB_RECLAIMABLE) +
237 global_page_state(NR_SLAB_UNRECLAIMABLE)),
238 K(global_page_state(NR_SLAB_RECLAIMABLE)),
239 K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
240 K(global_page_state(NR_PAGETABLE)),
241#ifdef CONFIG_QUICKLIST
242 K(quicklist_total_size()),
243#endif
244 K(global_page_state(NR_UNSTABLE_NFS)),
245 K(global_page_state(NR_BOUNCE)),
246 K(global_page_state(NR_WRITEBACK_TEMP)),
247 K(allowed),
248 K(committed),
249 (unsigned long)VMALLOC_TOTAL >> 10,
250 vmi.used >> 10,
251 vmi.largest_chunk >> 10
252 );
253
254 len += hugetlb_report_meminfo(page + len);
255
256 len += arch_report_meminfo(page + len);
257
258 return proc_calc_metrics(page, start, off, count, eof, len);
259#undef K
260}
261
262static int fragmentation_open(struct inode *inode, struct file *file)
263{
264 (void)inode;
265 return seq_open(file, &fragmentation_op);
266}
267
268static const struct file_operations fragmentation_file_operations = {
269 .open = fragmentation_open,
270 .read = seq_read,
271 .llseek = seq_lseek,
272 .release = seq_release,
273};
274
275static int pagetypeinfo_open(struct inode *inode, struct file *file)
276{
277 return seq_open(file, &pagetypeinfo_op);
278}
279
280static const struct file_operations pagetypeinfo_file_ops = {
281 .open = pagetypeinfo_open,
282 .read = seq_read,
283 .llseek = seq_lseek,
284 .release = seq_release,
285};
286
287static int zoneinfo_open(struct inode *inode, struct file *file)
288{
289 return seq_open(file, &zoneinfo_op);
290}
291
292static const struct file_operations proc_zoneinfo_file_operations = {
293 .open = zoneinfo_open,
294 .read = seq_read,
295 .llseek = seq_lseek,
296 .release = seq_release,
297};
298
299static int version_read_proc(char *page, char **start, off_t off,
300 int count, int *eof, void *data)
301{
302 int len;
303
304 len = snprintf(page, PAGE_SIZE, linux_proc_banner,
305 utsname()->sysname,
306 utsname()->release,
307 utsname()->version);
308 return proc_calc_metrics(page, start, off, count, eof, len);
309}
310
311extern const struct seq_operations cpuinfo_op;
312static int cpuinfo_open(struct inode *inode, struct file *file)
313{
314 return seq_open(file, &cpuinfo_op);
315}
316
317static const struct file_operations proc_cpuinfo_operations = {
318 .open = cpuinfo_open,
319 .read = seq_read,
320 .llseek = seq_lseek,
321 .release = seq_release,
322};
323
324static int devinfo_show(struct seq_file *f, void *v)
325{
326 int i = *(loff_t *) v;
327
328 if (i < CHRDEV_MAJOR_HASH_SIZE) {
329 if (i == 0)
330 seq_printf(f, "Character devices:\n");
331 chrdev_show(f, i);
332 }
333#ifdef CONFIG_BLOCK
334 else {
335 i -= CHRDEV_MAJOR_HASH_SIZE;
336 if (i == 0)
337 seq_printf(f, "\nBlock devices:\n");
338 blkdev_show(f, i);
339 }
340#endif
341 return 0;
342}
343
344static void *devinfo_start(struct seq_file *f, loff_t *pos)
345{
346 if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
347 return pos;
348 return NULL;
349}
350
351static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
352{
353 (*pos)++;
354 if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
355 return NULL;
356 return pos;
357}
358
359static void devinfo_stop(struct seq_file *f, void *v)
360{
361 /* Nothing to do */
362}
363
364static const struct seq_operations devinfo_ops = {
365 .start = devinfo_start,
366 .next = devinfo_next,
367 .stop = devinfo_stop,
368 .show = devinfo_show
369};
370
371static int devinfo_open(struct inode *inode, struct file *filp)
372{
373 return seq_open(filp, &devinfo_ops);
374}
375
376static const struct file_operations proc_devinfo_operations = {
377 .open = devinfo_open,
378 .read = seq_read,
379 .llseek = seq_lseek,
380 .release = seq_release,
381};
382
383static int vmstat_open(struct inode *inode, struct file *file)
384{
385 return seq_open(file, &vmstat_op);
386}
387static const struct file_operations proc_vmstat_file_operations = {
388 .open = vmstat_open,
389 .read = seq_read,
390 .llseek = seq_lseek,
391 .release = seq_release,
392};
393
394#ifdef CONFIG_PROC_HARDWARE
395static int hardware_read_proc(char *page, char **start, off_t off,
396 int count, int *eof, void *data)
397{
398 int len = get_hardware_list(page);
399 return proc_calc_metrics(page, start, off, count, eof, len);
400}
401#endif
402
403#ifdef CONFIG_STRAM_PROC
404static int stram_read_proc(char *page, char **start, off_t off,
405 int count, int *eof, void *data)
406{
407 int len = get_stram_list(page);
408 return proc_calc_metrics(page, start, off, count, eof, len);
409}
410#endif
411
412#ifdef CONFIG_BLOCK
413static int partitions_open(struct inode *inode, struct file *file)
414{
415 return seq_open(file, &partitions_op);
416}
417static const struct file_operations proc_partitions_operations = {
418 .open = partitions_open,
419 .read = seq_read,
420 .llseek = seq_lseek,
421 .release = seq_release,
422};
423
424static int diskstats_open(struct inode *inode, struct file *file)
425{
426 return seq_open(file, &diskstats_op);
427}
428static const struct file_operations proc_diskstats_operations = {
429 .open = diskstats_open,
430 .read = seq_read,
431 .llseek = seq_lseek,
432 .release = seq_release,
433};
434#endif
435
436#ifdef CONFIG_MODULES
437extern const struct seq_operations modules_op;
438static int modules_open(struct inode *inode, struct file *file)
439{
440 return seq_open(file, &modules_op);
441}
442static const struct file_operations proc_modules_operations = {
443 .open = modules_open,
444 .read = seq_read,
445 .llseek = seq_lseek,
446 .release = seq_release,
447};
448#endif
449
450#ifdef CONFIG_SLABINFO
451static int slabinfo_open(struct inode *inode, struct file *file)
452{
453 return seq_open(file, &slabinfo_op);
454}
455static const struct file_operations proc_slabinfo_operations = {
456 .open = slabinfo_open,
457 .read = seq_read,
458 .write = slabinfo_write,
459 .llseek = seq_lseek,
460 .release = seq_release,
461};
462
463#ifdef CONFIG_DEBUG_SLAB_LEAK
464extern const struct seq_operations slabstats_op;
465static int slabstats_open(struct inode *inode, struct file *file)
466{
467 unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
468 int ret = -ENOMEM;
469 if (n) {
470 ret = seq_open(file, &slabstats_op);
471 if (!ret) {
472 struct seq_file *m = file->private_data;
473 *n = PAGE_SIZE / (2 * sizeof(unsigned long));
474 m->private = n;
475 n = NULL;
476 }
477 kfree(n);
478 }
479 return ret;
480}
481
482static const struct file_operations proc_slabstats_operations = {
483 .open = slabstats_open,
484 .read = seq_read,
485 .llseek = seq_lseek,
486 .release = seq_release_private,
487};
488#endif
489#endif
490
491#ifdef CONFIG_MMU
492static int vmalloc_open(struct inode *inode, struct file *file)
493{
494 unsigned int *ptr = NULL;
495 int ret;
496
497 if (NUMA_BUILD)
498 ptr = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL);
499 ret = seq_open(file, &vmalloc_op);
500 if (!ret) {
501 struct seq_file *m = file->private_data;
502 m->private = ptr;
503 } else
504 kfree(ptr);
505 return ret;
506}
507
508static const struct file_operations proc_vmalloc_operations = {
509 .open = vmalloc_open,
510 .read = seq_read,
511 .llseek = seq_lseek,
512 .release = seq_release_private,
513};
514#endif
515
516#ifndef arch_irq_stat_cpu
517#define arch_irq_stat_cpu(cpu) 0
518#endif
519#ifndef arch_irq_stat
520#define arch_irq_stat() 0
521#endif
522
523static int show_stat(struct seq_file *p, void *v)
524{
525 int i, j;
526 unsigned long jif;
527 cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
528 cputime64_t guest;
529 u64 sum = 0;
530 struct timespec boottime;
531 unsigned int per_irq_sum;
532
533 user = nice = system = idle = iowait =
534 irq = softirq = steal = cputime64_zero;
535 guest = cputime64_zero;
536 getboottime(&boottime);
537 jif = boottime.tv_sec;
538
539 for_each_possible_cpu(i) {
540 user = cputime64_add(user, kstat_cpu(i).cpustat.user);
541 nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
542 system = cputime64_add(system, kstat_cpu(i).cpustat.system);
543 idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
544 iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
545 irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
546 softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
547 steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
548 guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
549
550 for_each_irq_nr(j)
551 sum += kstat_irqs_cpu(j, i);
552
553 sum += arch_irq_stat_cpu(i);
554 }
555 sum += arch_irq_stat();
556
557 seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
558 (unsigned long long)cputime64_to_clock_t(user),
559 (unsigned long long)cputime64_to_clock_t(nice),
560 (unsigned long long)cputime64_to_clock_t(system),
561 (unsigned long long)cputime64_to_clock_t(idle),
562 (unsigned long long)cputime64_to_clock_t(iowait),
563 (unsigned long long)cputime64_to_clock_t(irq),
564 (unsigned long long)cputime64_to_clock_t(softirq),
565 (unsigned long long)cputime64_to_clock_t(steal),
566 (unsigned long long)cputime64_to_clock_t(guest));
567 for_each_online_cpu(i) {
568
569 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
570 user = kstat_cpu(i).cpustat.user;
571 nice = kstat_cpu(i).cpustat.nice;
572 system = kstat_cpu(i).cpustat.system;
573 idle = kstat_cpu(i).cpustat.idle;
574 iowait = kstat_cpu(i).cpustat.iowait;
575 irq = kstat_cpu(i).cpustat.irq;
576 softirq = kstat_cpu(i).cpustat.softirq;
577 steal = kstat_cpu(i).cpustat.steal;
578 guest = kstat_cpu(i).cpustat.guest;
579 seq_printf(p,
580 "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
581 i,
582 (unsigned long long)cputime64_to_clock_t(user),
583 (unsigned long long)cputime64_to_clock_t(nice),
584 (unsigned long long)cputime64_to_clock_t(system),
585 (unsigned long long)cputime64_to_clock_t(idle),
586 (unsigned long long)cputime64_to_clock_t(iowait),
587 (unsigned long long)cputime64_to_clock_t(irq),
588 (unsigned long long)cputime64_to_clock_t(softirq),
589 (unsigned long long)cputime64_to_clock_t(steal),
590 (unsigned long long)cputime64_to_clock_t(guest));
591 }
592 seq_printf(p, "intr %llu", (unsigned long long)sum);
593
594 /* sum again ? it could be updated? */
595 for_each_irq_nr(j) {
596 per_irq_sum = 0;
597
598 for_each_possible_cpu(i)
599 per_irq_sum += kstat_irqs_cpu(j, i);
600
601 seq_printf(p, " %u", per_irq_sum);
602 }
603
604 seq_printf(p,
605 "\nctxt %llu\n"
606 "btime %lu\n"
607 "processes %lu\n"
608 "procs_running %lu\n"
609 "procs_blocked %lu\n",
610 nr_context_switches(),
611 (unsigned long)jif,
612 total_forks,
613 nr_running(),
614 nr_iowait());
615
616 return 0;
617}
618
619static int stat_open(struct inode *inode, struct file *file)
620{
621 unsigned size = 4096 * (1 + num_possible_cpus() / 32);
622 char *buf;
623 struct seq_file *m;
624 int res;
625
626 /* don't ask for more than the kmalloc() max size, currently 128 KB */
627 if (size > 128 * 1024)
628 size = 128 * 1024;
629 buf = kmalloc(size, GFP_KERNEL);
630 if (!buf)
631 return -ENOMEM;
632
633 res = single_open(file, show_stat, NULL);
634 if (!res) {
635 m = file->private_data;
636 m->buf = buf;
637 m->size = size;
638 } else
639 kfree(buf);
640 return res;
641}
642static const struct file_operations proc_stat_operations = {
643 .open = stat_open,
644 .read = seq_read,
645 .llseek = seq_lseek,
646 .release = single_release,
647};
648
649/*
650 * /proc/interrupts
651 */
652static void *int_seq_start(struct seq_file *f, loff_t *pos)
653{
654 return (*pos <= nr_irqs) ? pos : NULL;
655}
656
657
658static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
659{
660 (*pos)++;
661 return (*pos <= nr_irqs) ? pos : NULL;
662}
663
664static void int_seq_stop(struct seq_file *f, void *v)
665{
666 /* Nothing to do */
667}
668
669static const struct seq_operations int_seq_ops = {
670 .start = int_seq_start,
671 .next = int_seq_next,
672 .stop = int_seq_stop,
673 .show = show_interrupts
674};
675
676static int interrupts_open(struct inode *inode, struct file *filp)
677{
678 return seq_open(filp, &int_seq_ops);
679}
680
681static const struct file_operations proc_interrupts_operations = {
682 .open = interrupts_open,
683 .read = seq_read,
684 .llseek = seq_lseek,
685 .release = seq_release,
686};
687
688static int filesystems_read_proc(char *page, char **start, off_t off,
689 int count, int *eof, void *data)
690{
691 int len = get_filesystem_list(page);
692 return proc_calc_metrics(page, start, off, count, eof, len);
693}
694
695static int cmdline_read_proc(char *page, char **start, off_t off,
696 int count, int *eof, void *data)
697{
698 int len;
699
700 len = sprintf(page, "%s\n", saved_command_line);
701 return proc_calc_metrics(page, start, off, count, eof, len);
702}
703
704#ifdef CONFIG_FILE_LOCKING
705static int locks_open(struct inode *inode, struct file *filp)
706{
707 return seq_open(filp, &locks_seq_operations);
708}
709
710static const struct file_operations proc_locks_operations = {
711 .open = locks_open,
712 .read = seq_read,
713 .llseek = seq_lseek,
714 .release = seq_release,
715};
716#endif /* CONFIG_FILE_LOCKING */
717
718static int execdomains_read_proc(char *page, char **start, off_t off,
719 int count, int *eof, void *data)
720{
721 int len = get_exec_domain_list(page);
722 return proc_calc_metrics(page, start, off, count, eof, len);
723}
724
725#ifdef CONFIG_PROC_PAGE_MONITOR
726#define KPMSIZE sizeof(u64)
727#define KPMMASK (KPMSIZE - 1)
728/* /proc/kpagecount - an array exposing page counts
729 *
730 * Each entry is a u64 representing the corresponding
731 * physical page count.
732 */
733static ssize_t kpagecount_read(struct file *file, char __user *buf,
734 size_t count, loff_t *ppos)
735{
736 u64 __user *out = (u64 __user *)buf;
737 struct page *ppage;
738 unsigned long src = *ppos;
739 unsigned long pfn;
740 ssize_t ret = 0;
741 u64 pcount;
742
743 pfn = src / KPMSIZE;
744 count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
745 if (src & KPMMASK || count & KPMMASK)
746 return -EINVAL;
747
748 while (count > 0) {
749 ppage = NULL;
750 if (pfn_valid(pfn))
751 ppage = pfn_to_page(pfn);
752 pfn++;
753 if (!ppage)
754 pcount = 0;
755 else
756 pcount = page_mapcount(ppage);
757
758 if (put_user(pcount, out++)) {
759 ret = -EFAULT;
760 break;
761 }
762
763 count -= KPMSIZE;
764 }
765
766 *ppos += (char __user *)out - buf;
767 if (!ret)
768 ret = (char __user *)out - buf;
769 return ret;
770}
771
772static struct file_operations proc_kpagecount_operations = {
773 .llseek = mem_lseek,
774 .read = kpagecount_read,
775};
776
777/* /proc/kpageflags - an array exposing page flags
778 *
779 * Each entry is a u64 representing the corresponding
780 * physical page flags.
781 */
782
783/* These macros are used to decouple internal flags from exported ones */
784
785#define KPF_LOCKED 0
786#define KPF_ERROR 1
787#define KPF_REFERENCED 2
788#define KPF_UPTODATE 3
789#define KPF_DIRTY 4
790#define KPF_LRU 5
791#define KPF_ACTIVE 6
792#define KPF_SLAB 7
793#define KPF_WRITEBACK 8
794#define KPF_RECLAIM 9
795#define KPF_BUDDY 10
796
797#define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos)
798
799static ssize_t kpageflags_read(struct file *file, char __user *buf,
800 size_t count, loff_t *ppos)
801{
802 u64 __user *out = (u64 __user *)buf;
803 struct page *ppage;
804 unsigned long src = *ppos;
805 unsigned long pfn;
806 ssize_t ret = 0;
807 u64 kflags, uflags;
808
809 pfn = src / KPMSIZE;
810 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
811 if (src & KPMMASK || count & KPMMASK)
812 return -EINVAL;
813
814 while (count > 0) {
815 ppage = NULL;
816 if (pfn_valid(pfn))
817 ppage = pfn_to_page(pfn);
818 pfn++;
819 if (!ppage)
820 kflags = 0;
821 else
822 kflags = ppage->flags;
823
824 uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) |
825 kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
826 kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
827 kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
828 kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
829 kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
830 kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
831 kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
832 kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
833 kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
834 kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
835
836 if (put_user(uflags, out++)) {
837 ret = -EFAULT;
838 break;
839 }
840
841 count -= KPMSIZE;
842 }
843
844 *ppos += (char __user *)out - buf;
845 if (!ret)
846 ret = (char __user *)out - buf;
847 return ret;
848}
849
850static struct file_operations proc_kpageflags_operations = {
851 .llseek = mem_lseek,
852 .read = kpageflags_read,
853};
854#endif /* CONFIG_PROC_PAGE_MONITOR */
855
856struct proc_dir_entry *proc_root_kcore;
857
858void __init proc_misc_init(void)
859{
860 static struct {
861 char *name;
862 int (*read_proc)(char*,char**,off_t,int,int*,void*);
863 } *p, simple_ones[] = {
864 {"loadavg", loadavg_read_proc},
865 {"uptime", uptime_read_proc},
866 {"meminfo", meminfo_read_proc},
867 {"version", version_read_proc},
868#ifdef CONFIG_PROC_HARDWARE
869 {"hardware", hardware_read_proc},
870#endif
871#ifdef CONFIG_STRAM_PROC
872 {"stram", stram_read_proc},
873#endif
874 {"filesystems", filesystems_read_proc},
875 {"cmdline", cmdline_read_proc},
876 {"execdomains", execdomains_read_proc},
877 {NULL,}
878 };
879 for (p = simple_ones; p->name; p++)
880 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
881
882 proc_symlink("mounts", NULL, "self/mounts");
883
884 /* And now for trickier ones */
885#ifdef CONFIG_PRINTK
886 proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
887#endif
888#ifdef CONFIG_FILE_LOCKING
889 proc_create("locks", 0, NULL, &proc_locks_operations);
890#endif
891 proc_create("devices", 0, NULL, &proc_devinfo_operations);
892 proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
893#ifdef CONFIG_BLOCK
894 proc_create("partitions", 0, NULL, &proc_partitions_operations);
895#endif
896 proc_create("stat", 0, NULL, &proc_stat_operations);
897 proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
898#ifdef CONFIG_SLABINFO
899 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
900#ifdef CONFIG_DEBUG_SLAB_LEAK
901 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
902#endif
903#endif
904#ifdef CONFIG_MMU
905 proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations);
906#endif
907 proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
908 proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
909 proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
910 proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
911#ifdef CONFIG_BLOCK
912 proc_create("diskstats", 0, NULL, &proc_diskstats_operations);
913#endif
914#ifdef CONFIG_MODULES
915 proc_create("modules", 0, NULL, &proc_modules_operations);
916#endif
917#ifdef CONFIG_SCHEDSTATS
918 proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
919#endif
920#ifdef CONFIG_PROC_KCORE
921 proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
922 if (proc_root_kcore)
923 proc_root_kcore->size =
924 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
925#endif
926#ifdef CONFIG_PROC_PAGE_MONITOR
927 proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
928 proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
929#endif
930#ifdef CONFIG_PROC_VMCORE
931 proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
932#endif
933}
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 7b997754a25e..94fcfff6863a 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * /proc/sys support 2 * /proc/sys support
3 */ 3 */
4 4#include <linux/init.h>
5#include <linux/sysctl.h> 5#include <linux/sysctl.h>
6#include <linux/proc_fs.h> 6#include <linux/proc_fs.h>
7#include <linux/security.h> 7#include <linux/security.h>
@@ -402,7 +402,7 @@ static struct dentry_operations proc_sys_dentry_operations = {
402 .d_compare = proc_sys_compare, 402 .d_compare = proc_sys_compare,
403}; 403};
404 404
405int proc_sys_init(void) 405int __init proc_sys_init(void)
406{ 406{
407 struct proc_dir_entry *proc_sys_root; 407 struct proc_dir_entry *proc_sys_root;
408 408
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 95117538a4f6..7761602af9de 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -104,9 +104,9 @@ static struct file_system_type proc_fs_type = {
104 104
105void __init proc_root_init(void) 105void __init proc_root_init(void)
106{ 106{
107 int err = proc_init_inodecache(); 107 int err;
108 if (err) 108
109 return; 109 proc_init_inodecache();
110 err = register_filesystem(&proc_fs_type); 110 err = register_filesystem(&proc_fs_type);
111 if (err) 111 if (err)
112 return; 112 return;
@@ -117,7 +117,7 @@ void __init proc_root_init(void)
117 return; 117 return;
118 } 118 }
119 119
120 proc_misc_init(); 120 proc_symlink("mounts", NULL, "self/mounts");
121 121
122 proc_net_init(); 122 proc_net_init();
123 123
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
new file mode 100644
index 000000000000..81904f07679d
--- /dev/null
+++ b/fs/proc/stat.c
@@ -0,0 +1,153 @@
1#include <linux/cpumask.h>
2#include <linux/fs.h>
3#include <linux/gfp.h>
4#include <linux/init.h>
5#include <linux/interrupt.h>
6#include <linux/kernel_stat.h>
7#include <linux/proc_fs.h>
8#include <linux/sched.h>
9#include <linux/seq_file.h>
10#include <linux/slab.h>
11#include <linux/time.h>
12#include <asm/cputime.h>
13
14#ifndef arch_irq_stat_cpu
15#define arch_irq_stat_cpu(cpu) 0
16#endif
17#ifndef arch_irq_stat
18#define arch_irq_stat() 0
19#endif
20
21static int show_stat(struct seq_file *p, void *v)
22{
23 int i, j;
24 unsigned long jif;
25 cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
26 cputime64_t guest;
27 u64 sum = 0;
28 struct timespec boottime;
29 unsigned int per_irq_sum;
30
31 user = nice = system = idle = iowait =
32 irq = softirq = steal = cputime64_zero;
33 guest = cputime64_zero;
34 getboottime(&boottime);
35 jif = boottime.tv_sec;
36
37 for_each_possible_cpu(i) {
38 user = cputime64_add(user, kstat_cpu(i).cpustat.user);
39 nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
40 system = cputime64_add(system, kstat_cpu(i).cpustat.system);
41 idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
42 iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
43 irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
44 softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
45 steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
46 guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
47
48 for_each_irq_nr(j)
49 sum += kstat_irqs_cpu(j, i);
50
51 sum += arch_irq_stat_cpu(i);
52 }
53 sum += arch_irq_stat();
54
55 seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
56 (unsigned long long)cputime64_to_clock_t(user),
57 (unsigned long long)cputime64_to_clock_t(nice),
58 (unsigned long long)cputime64_to_clock_t(system),
59 (unsigned long long)cputime64_to_clock_t(idle),
60 (unsigned long long)cputime64_to_clock_t(iowait),
61 (unsigned long long)cputime64_to_clock_t(irq),
62 (unsigned long long)cputime64_to_clock_t(softirq),
63 (unsigned long long)cputime64_to_clock_t(steal),
64 (unsigned long long)cputime64_to_clock_t(guest));
65 for_each_online_cpu(i) {
66
67 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
68 user = kstat_cpu(i).cpustat.user;
69 nice = kstat_cpu(i).cpustat.nice;
70 system = kstat_cpu(i).cpustat.system;
71 idle = kstat_cpu(i).cpustat.idle;
72 iowait = kstat_cpu(i).cpustat.iowait;
73 irq = kstat_cpu(i).cpustat.irq;
74 softirq = kstat_cpu(i).cpustat.softirq;
75 steal = kstat_cpu(i).cpustat.steal;
76 guest = kstat_cpu(i).cpustat.guest;
77 seq_printf(p,
78 "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
79 i,
80 (unsigned long long)cputime64_to_clock_t(user),
81 (unsigned long long)cputime64_to_clock_t(nice),
82 (unsigned long long)cputime64_to_clock_t(system),
83 (unsigned long long)cputime64_to_clock_t(idle),
84 (unsigned long long)cputime64_to_clock_t(iowait),
85 (unsigned long long)cputime64_to_clock_t(irq),
86 (unsigned long long)cputime64_to_clock_t(softirq),
87 (unsigned long long)cputime64_to_clock_t(steal),
88 (unsigned long long)cputime64_to_clock_t(guest));
89 }
90 seq_printf(p, "intr %llu", (unsigned long long)sum);
91
92 /* sum again ? it could be updated? */
93 for_each_irq_nr(j) {
94 per_irq_sum = 0;
95
96 for_each_possible_cpu(i)
97 per_irq_sum += kstat_irqs_cpu(j, i);
98
99 seq_printf(p, " %u", per_irq_sum);
100 }
101
102 seq_printf(p,
103 "\nctxt %llu\n"
104 "btime %lu\n"
105 "processes %lu\n"
106 "procs_running %lu\n"
107 "procs_blocked %lu\n",
108 nr_context_switches(),
109 (unsigned long)jif,
110 total_forks,
111 nr_running(),
112 nr_iowait());
113
114 return 0;
115}
116
117static int stat_open(struct inode *inode, struct file *file)
118{
119 unsigned size = 4096 * (1 + num_possible_cpus() / 32);
120 char *buf;
121 struct seq_file *m;
122 int res;
123
124 /* don't ask for more than the kmalloc() max size, currently 128 KB */
125 if (size > 128 * 1024)
126 size = 128 * 1024;
127 buf = kmalloc(size, GFP_KERNEL);
128 if (!buf)
129 return -ENOMEM;
130
131 res = single_open(file, show_stat, NULL);
132 if (!res) {
133 m = file->private_data;
134 m->buf = buf;
135 m->size = size;
136 } else
137 kfree(buf);
138 return res;
139}
140
141static const struct file_operations proc_stat_operations = {
142 .open = stat_open,
143 .read = seq_read,
144 .llseek = seq_lseek,
145 .release = single_release,
146};
147
148static int __init proc_stat_init(void)
149{
150 proc_create("stat", 0, NULL, &proc_stat_operations);
151 return 0;
152}
153module_init(proc_stat_init);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 4806830ea2a1..b770c095e45c 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -198,11 +198,8 @@ static int do_maps_open(struct inode *inode, struct file *file,
198 return ret; 198 return ret;
199} 199}
200 200
201static int show_map(struct seq_file *m, void *v) 201static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
202{ 202{
203 struct proc_maps_private *priv = m->private;
204 struct task_struct *task = priv->task;
205 struct vm_area_struct *vma = v;
206 struct mm_struct *mm = vma->vm_mm; 203 struct mm_struct *mm = vma->vm_mm;
207 struct file *file = vma->vm_file; 204 struct file *file = vma->vm_file;
208 int flags = vma->vm_flags; 205 int flags = vma->vm_flags;
@@ -254,6 +251,15 @@ static int show_map(struct seq_file *m, void *v)
254 } 251 }
255 } 252 }
256 seq_putc(m, '\n'); 253 seq_putc(m, '\n');
254}
255
256static int show_map(struct seq_file *m, void *v)
257{
258 struct vm_area_struct *vma = v;
259 struct proc_maps_private *priv = m->private;
260 struct task_struct *task = priv->task;
261
262 show_map_vma(m, vma);
257 263
258 if (m->count < m->size) /* vma is copied successfully */ 264 if (m->count < m->size) /* vma is copied successfully */
259 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0; 265 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
@@ -364,9 +370,10 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
364 370
365static int show_smap(struct seq_file *m, void *v) 371static int show_smap(struct seq_file *m, void *v)
366{ 372{
373 struct proc_maps_private *priv = m->private;
374 struct task_struct *task = priv->task;
367 struct vm_area_struct *vma = v; 375 struct vm_area_struct *vma = v;
368 struct mem_size_stats mss; 376 struct mem_size_stats mss;
369 int ret;
370 struct mm_walk smaps_walk = { 377 struct mm_walk smaps_walk = {
371 .pmd_entry = smaps_pte_range, 378 .pmd_entry = smaps_pte_range,
372 .mm = vma->vm_mm, 379 .mm = vma->vm_mm,
@@ -378,9 +385,7 @@ static int show_smap(struct seq_file *m, void *v)
378 if (vma->vm_mm && !is_vm_hugetlb_page(vma)) 385 if (vma->vm_mm && !is_vm_hugetlb_page(vma))
379 walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk); 386 walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
380 387
381 ret = show_map(m, v); 388 show_map_vma(m, vma);
382 if (ret)
383 return ret;
384 389
385 seq_printf(m, 390 seq_printf(m,
386 "Size: %8lu kB\n" 391 "Size: %8lu kB\n"
@@ -402,7 +407,9 @@ static int show_smap(struct seq_file *m, void *v)
402 mss.referenced >> 10, 407 mss.referenced >> 10,
403 mss.swap >> 10); 408 mss.swap >> 10);
404 409
405 return ret; 410 if (m->count < m->size) /* vma is copied successfully */
411 m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
412 return 0;
406} 413}
407 414
408static const struct seq_operations proc_pid_smaps_op = { 415static const struct seq_operations proc_pid_smaps_op = {
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
new file mode 100644
index 000000000000..0c10a0b3f146
--- /dev/null
+++ b/fs/proc/uptime.c
@@ -0,0 +1,43 @@
1#include <linux/fs.h>
2#include <linux/init.h>
3#include <linux/proc_fs.h>
4#include <linux/sched.h>
5#include <linux/seq_file.h>
6#include <linux/time.h>
7#include <asm/cputime.h>
8
9static int uptime_proc_show(struct seq_file *m, void *v)
10{
11 struct timespec uptime;
12 struct timespec idle;
13 cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
14
15 do_posix_clock_monotonic_gettime(&uptime);
16 monotonic_to_bootbased(&uptime);
17 cputime_to_timespec(idletime, &idle);
18 seq_printf(m, "%lu.%02lu %lu.%02lu\n",
19 (unsigned long) uptime.tv_sec,
20 (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
21 (unsigned long) idle.tv_sec,
22 (idle.tv_nsec / (NSEC_PER_SEC / 100)));
23 return 0;
24}
25
26static int uptime_proc_open(struct inode *inode, struct file *file)
27{
28 return single_open(file, uptime_proc_show, NULL);
29}
30
31static const struct file_operations uptime_proc_fops = {
32 .open = uptime_proc_open,
33 .read = seq_read,
34 .llseek = seq_lseek,
35 .release = single_release,
36};
37
38static int __init proc_uptime_init(void)
39{
40 proc_create("uptime", 0, NULL, &uptime_proc_fops);
41 return 0;
42}
43module_init(proc_uptime_init);
diff --git a/fs/proc/version.c b/fs/proc/version.c
new file mode 100644
index 000000000000..76817a60678c
--- /dev/null
+++ b/fs/proc/version.c
@@ -0,0 +1,34 @@
1#include <linux/fs.h>
2#include <linux/init.h>
3#include <linux/kernel.h>
4#include <linux/proc_fs.h>
5#include <linux/seq_file.h>
6#include <linux/utsname.h>
7
8static int version_proc_show(struct seq_file *m, void *v)
9{
10 seq_printf(m, linux_proc_banner,
11 utsname()->sysname,
12 utsname()->release,
13 utsname()->version);
14 return 0;
15}
16
17static int version_proc_open(struct inode *inode, struct file *file)
18{
19 return single_open(file, version_proc_show, NULL);
20}
21
22static const struct file_operations version_proc_fops = {
23 .open = version_proc_open,
24 .read = seq_read,
25 .llseek = seq_lseek,
26 .release = single_release,
27};
28
29static int __init proc_version_init(void)
30{
31 proc_create("version", 0, NULL, &version_proc_fops);
32 return 0;
33}
34module_init(proc_version_init);
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index cd9ca67f841b..03ec59504906 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -32,7 +32,7 @@ static size_t elfcorebuf_sz;
32/* Total size of vmcore file. */ 32/* Total size of vmcore file. */
33static u64 vmcore_size; 33static u64 vmcore_size;
34 34
35struct proc_dir_entry *proc_vmcore = NULL; 35static struct proc_dir_entry *proc_vmcore = NULL;
36 36
37/* Reads a page from the oldmem device from given offset. */ 37/* Reads a page from the oldmem device from given offset. */
38static ssize_t read_from_oldmem(char *buf, size_t count, 38static ssize_t read_from_oldmem(char *buf, size_t count,
@@ -162,7 +162,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
162 return acc; 162 return acc;
163} 163}
164 164
165const struct file_operations proc_vmcore_operations = { 165static const struct file_operations proc_vmcore_operations = {
166 .read = read_vmcore, 166 .read = read_vmcore,
167}; 167};
168 168
@@ -652,7 +652,7 @@ static int __init vmcore_init(void)
652 return rc; 652 return rc;
653 } 653 }
654 654
655 /* Initialize /proc/vmcore size if proc is already up. */ 655 proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
656 if (proc_vmcore) 656 if (proc_vmcore)
657 proc_vmcore->size = vmcore_size; 657 proc_vmcore->size = vmcore_size;
658 return 0; 658 return 0;