diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/base.c | 235 | ||||
-rw-r--r-- | fs/proc/generic.c | 8 | ||||
-rw-r--r-- | fs/proc/inode.c | 3 | ||||
-rw-r--r-- | fs/proc/internal.h | 2 | ||||
-rw-r--r-- | fs/proc/meminfo.c | 6 | ||||
-rw-r--r-- | fs/proc/nommu.c | 71 | ||||
-rw-r--r-- | fs/proc/proc_net.c | 2 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 1 | ||||
-rw-r--r-- | fs/proc/root.c | 8 | ||||
-rw-r--r-- | fs/proc/stat.c | 11 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 8 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 122 | ||||
-rw-r--r-- | fs/proc/vmcore.c | 2 |
13 files changed, 267 insertions, 212 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index cad92c1ac2b3..0c9de19a1633 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #include <linux/mm.h> | 65 | #include <linux/mm.h> |
66 | #include <linux/rcupdate.h> | 66 | #include <linux/rcupdate.h> |
67 | #include <linux/kallsyms.h> | 67 | #include <linux/kallsyms.h> |
68 | #include <linux/stacktrace.h> | ||
68 | #include <linux/resource.h> | 69 | #include <linux/resource.h> |
69 | #include <linux/module.h> | 70 | #include <linux/module.h> |
70 | #include <linux/mount.h> | 71 | #include <linux/mount.h> |
@@ -109,25 +110,22 @@ struct pid_entry { | |||
109 | .op = OP, \ | 110 | .op = OP, \ |
110 | } | 111 | } |
111 | 112 | ||
112 | #define DIR(NAME, MODE, OTYPE) \ | 113 | #define DIR(NAME, MODE, iops, fops) \ |
113 | NOD(NAME, (S_IFDIR|(MODE)), \ | 114 | NOD(NAME, (S_IFDIR|(MODE)), &iops, &fops, {} ) |
114 | &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations, \ | 115 | #define LNK(NAME, get_link) \ |
115 | {} ) | ||
116 | #define LNK(NAME, OTYPE) \ | ||
117 | NOD(NAME, (S_IFLNK|S_IRWXUGO), \ | 116 | NOD(NAME, (S_IFLNK|S_IRWXUGO), \ |
118 | &proc_pid_link_inode_operations, NULL, \ | 117 | &proc_pid_link_inode_operations, NULL, \ |
119 | { .proc_get_link = &proc_##OTYPE##_link } ) | 118 | { .proc_get_link = get_link } ) |
120 | #define REG(NAME, MODE, OTYPE) \ | 119 | #define REG(NAME, MODE, fops) \ |
121 | NOD(NAME, (S_IFREG|(MODE)), NULL, \ | 120 | NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {}) |
122 | &proc_##OTYPE##_operations, {}) | 121 | #define INF(NAME, MODE, read) \ |
123 | #define INF(NAME, MODE, OTYPE) \ | ||
124 | NOD(NAME, (S_IFREG|(MODE)), \ | 122 | NOD(NAME, (S_IFREG|(MODE)), \ |
125 | NULL, &proc_info_file_operations, \ | 123 | NULL, &proc_info_file_operations, \ |
126 | { .proc_read = &proc_##OTYPE } ) | 124 | { .proc_read = read } ) |
127 | #define ONE(NAME, MODE, OTYPE) \ | 125 | #define ONE(NAME, MODE, show) \ |
128 | NOD(NAME, (S_IFREG|(MODE)), \ | 126 | NOD(NAME, (S_IFREG|(MODE)), \ |
129 | NULL, &proc_single_file_operations, \ | 127 | NULL, &proc_single_file_operations, \ |
130 | { .proc_show = &proc_##OTYPE } ) | 128 | { .proc_show = show } ) |
131 | 129 | ||
132 | /* | 130 | /* |
133 | * Count the number of hardlinks for the pid_entry table, excluding the . | 131 | * Count the number of hardlinks for the pid_entry table, excluding the . |
@@ -308,9 +306,9 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer) | |||
308 | struct mm_struct *mm = get_task_mm(task); | 306 | struct mm_struct *mm = get_task_mm(task); |
309 | if (mm) { | 307 | if (mm) { |
310 | unsigned int nwords = 0; | 308 | unsigned int nwords = 0; |
311 | do | 309 | do { |
312 | nwords += 2; | 310 | nwords += 2; |
313 | while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ | 311 | } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ |
314 | res = nwords * sizeof(mm->saved_auxv[0]); | 312 | res = nwords * sizeof(mm->saved_auxv[0]); |
315 | if (res > PAGE_SIZE) | 313 | if (res > PAGE_SIZE) |
316 | res = PAGE_SIZE; | 314 | res = PAGE_SIZE; |
@@ -340,6 +338,37 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer) | |||
340 | } | 338 | } |
341 | #endif /* CONFIG_KALLSYMS */ | 339 | #endif /* CONFIG_KALLSYMS */ |
342 | 340 | ||
341 | #ifdef CONFIG_STACKTRACE | ||
342 | |||
343 | #define MAX_STACK_TRACE_DEPTH 64 | ||
344 | |||
345 | static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns, | ||
346 | struct pid *pid, struct task_struct *task) | ||
347 | { | ||
348 | struct stack_trace trace; | ||
349 | unsigned long *entries; | ||
350 | int i; | ||
351 | |||
352 | entries = kmalloc(MAX_STACK_TRACE_DEPTH * sizeof(*entries), GFP_KERNEL); | ||
353 | if (!entries) | ||
354 | return -ENOMEM; | ||
355 | |||
356 | trace.nr_entries = 0; | ||
357 | trace.max_entries = MAX_STACK_TRACE_DEPTH; | ||
358 | trace.entries = entries; | ||
359 | trace.skip = 0; | ||
360 | save_stack_trace_tsk(task, &trace); | ||
361 | |||
362 | for (i = 0; i < trace.nr_entries; i++) { | ||
363 | seq_printf(m, "[<%p>] %pS\n", | ||
364 | (void *)entries[i], (void *)entries[i]); | ||
365 | } | ||
366 | kfree(entries); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | #endif | ||
371 | |||
343 | #ifdef CONFIG_SCHEDSTATS | 372 | #ifdef CONFIG_SCHEDSTATS |
344 | /* | 373 | /* |
345 | * Provides /proc/PID/schedstat | 374 | * Provides /proc/PID/schedstat |
@@ -1186,8 +1215,6 @@ static int sched_show(struct seq_file *m, void *v) | |||
1186 | struct inode *inode = m->private; | 1215 | struct inode *inode = m->private; |
1187 | struct task_struct *p; | 1216 | struct task_struct *p; |
1188 | 1217 | ||
1189 | WARN_ON(!inode); | ||
1190 | |||
1191 | p = get_proc_task(inode); | 1218 | p = get_proc_task(inode); |
1192 | if (!p) | 1219 | if (!p) |
1193 | return -ESRCH; | 1220 | return -ESRCH; |
@@ -1205,8 +1232,6 @@ sched_write(struct file *file, const char __user *buf, | |||
1205 | struct inode *inode = file->f_path.dentry->d_inode; | 1232 | struct inode *inode = file->f_path.dentry->d_inode; |
1206 | struct task_struct *p; | 1233 | struct task_struct *p; |
1207 | 1234 | ||
1208 | WARN_ON(!inode); | ||
1209 | |||
1210 | p = get_proc_task(inode); | 1235 | p = get_proc_task(inode); |
1211 | if (!p) | 1236 | if (!p) |
1212 | return -ESRCH; | 1237 | return -ESRCH; |
@@ -1426,8 +1451,6 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st | |||
1426 | if (!ei->pid) | 1451 | if (!ei->pid) |
1427 | goto out_unlock; | 1452 | goto out_unlock; |
1428 | 1453 | ||
1429 | inode->i_uid = 0; | ||
1430 | inode->i_gid = 0; | ||
1431 | if (task_dumpable(task)) { | 1454 | if (task_dumpable(task)) { |
1432 | rcu_read_lock(); | 1455 | rcu_read_lock(); |
1433 | cred = __task_cred(task); | 1456 | cred = __task_cred(task); |
@@ -1976,13 +1999,11 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
1976 | const struct pid_entry *ents, | 1999 | const struct pid_entry *ents, |
1977 | unsigned int nents) | 2000 | unsigned int nents) |
1978 | { | 2001 | { |
1979 | struct inode *inode; | ||
1980 | struct dentry *error; | 2002 | struct dentry *error; |
1981 | struct task_struct *task = get_proc_task(dir); | 2003 | struct task_struct *task = get_proc_task(dir); |
1982 | const struct pid_entry *p, *last; | 2004 | const struct pid_entry *p, *last; |
1983 | 2005 | ||
1984 | error = ERR_PTR(-ENOENT); | 2006 | error = ERR_PTR(-ENOENT); |
1985 | inode = NULL; | ||
1986 | 2007 | ||
1987 | if (!task) | 2008 | if (!task) |
1988 | goto out_no_task; | 2009 | goto out_no_task; |
@@ -2138,12 +2159,12 @@ static const struct file_operations proc_pid_attr_operations = { | |||
2138 | }; | 2159 | }; |
2139 | 2160 | ||
2140 | static const struct pid_entry attr_dir_stuff[] = { | 2161 | static const struct pid_entry attr_dir_stuff[] = { |
2141 | REG("current", S_IRUGO|S_IWUGO, pid_attr), | 2162 | REG("current", S_IRUGO|S_IWUGO, proc_pid_attr_operations), |
2142 | REG("prev", S_IRUGO, pid_attr), | 2163 | REG("prev", S_IRUGO, proc_pid_attr_operations), |
2143 | REG("exec", S_IRUGO|S_IWUGO, pid_attr), | 2164 | REG("exec", S_IRUGO|S_IWUGO, proc_pid_attr_operations), |
2144 | REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), | 2165 | REG("fscreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), |
2145 | REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), | 2166 | REG("keycreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), |
2146 | REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), | 2167 | REG("sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), |
2147 | }; | 2168 | }; |
2148 | 2169 | ||
2149 | static int proc_attr_dir_readdir(struct file * filp, | 2170 | static int proc_attr_dir_readdir(struct file * filp, |
@@ -2349,8 +2370,6 @@ static struct dentry *proc_base_instantiate(struct inode *dir, | |||
2349 | if (!ei->pid) | 2370 | if (!ei->pid) |
2350 | goto out_iput; | 2371 | goto out_iput; |
2351 | 2372 | ||
2352 | inode->i_uid = 0; | ||
2353 | inode->i_gid = 0; | ||
2354 | inode->i_mode = p->mode; | 2373 | inode->i_mode = p->mode; |
2355 | if (S_ISDIR(inode->i_mode)) | 2374 | if (S_ISDIR(inode->i_mode)) |
2356 | inode->i_nlink = 2; | 2375 | inode->i_nlink = 2; |
@@ -2465,74 +2484,77 @@ static const struct file_operations proc_task_operations; | |||
2465 | static const struct inode_operations proc_task_inode_operations; | 2484 | static const struct inode_operations proc_task_inode_operations; |
2466 | 2485 | ||
2467 | static const struct pid_entry tgid_base_stuff[] = { | 2486 | static const struct pid_entry tgid_base_stuff[] = { |
2468 | DIR("task", S_IRUGO|S_IXUGO, task), | 2487 | DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations), |
2469 | DIR("fd", S_IRUSR|S_IXUSR, fd), | 2488 | DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), |
2470 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | 2489 | DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations), |
2471 | #ifdef CONFIG_NET | 2490 | #ifdef CONFIG_NET |
2472 | DIR("net", S_IRUGO|S_IXUGO, net), | 2491 | DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations), |
2473 | #endif | 2492 | #endif |
2474 | REG("environ", S_IRUSR, environ), | 2493 | REG("environ", S_IRUSR, proc_environ_operations), |
2475 | INF("auxv", S_IRUSR, pid_auxv), | 2494 | INF("auxv", S_IRUSR, proc_pid_auxv), |
2476 | ONE("status", S_IRUGO, pid_status), | 2495 | ONE("status", S_IRUGO, proc_pid_status), |
2477 | ONE("personality", S_IRUSR, pid_personality), | 2496 | ONE("personality", S_IRUSR, proc_pid_personality), |
2478 | INF("limits", S_IRUSR, pid_limits), | 2497 | INF("limits", S_IRUSR, proc_pid_limits), |
2479 | #ifdef CONFIG_SCHED_DEBUG | 2498 | #ifdef CONFIG_SCHED_DEBUG |
2480 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2499 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2481 | #endif | 2500 | #endif |
2482 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2501 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2483 | INF("syscall", S_IRUSR, pid_syscall), | 2502 | INF("syscall", S_IRUSR, proc_pid_syscall), |
2484 | #endif | 2503 | #endif |
2485 | INF("cmdline", S_IRUGO, pid_cmdline), | 2504 | INF("cmdline", S_IRUGO, proc_pid_cmdline), |
2486 | ONE("stat", S_IRUGO, tgid_stat), | 2505 | ONE("stat", S_IRUGO, proc_tgid_stat), |
2487 | ONE("statm", S_IRUGO, pid_statm), | 2506 | ONE("statm", S_IRUGO, proc_pid_statm), |
2488 | REG("maps", S_IRUGO, maps), | 2507 | REG("maps", S_IRUGO, proc_maps_operations), |
2489 | #ifdef CONFIG_NUMA | 2508 | #ifdef CONFIG_NUMA |
2490 | REG("numa_maps", S_IRUGO, numa_maps), | 2509 | REG("numa_maps", S_IRUGO, proc_numa_maps_operations), |
2491 | #endif | 2510 | #endif |
2492 | REG("mem", S_IRUSR|S_IWUSR, mem), | 2511 | REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations), |
2493 | LNK("cwd", cwd), | 2512 | LNK("cwd", proc_cwd_link), |
2494 | LNK("root", root), | 2513 | LNK("root", proc_root_link), |
2495 | LNK("exe", exe), | 2514 | LNK("exe", proc_exe_link), |
2496 | REG("mounts", S_IRUGO, mounts), | 2515 | REG("mounts", S_IRUGO, proc_mounts_operations), |
2497 | REG("mountinfo", S_IRUGO, mountinfo), | 2516 | REG("mountinfo", S_IRUGO, proc_mountinfo_operations), |
2498 | REG("mountstats", S_IRUSR, mountstats), | 2517 | REG("mountstats", S_IRUSR, proc_mountstats_operations), |
2499 | #ifdef CONFIG_PROC_PAGE_MONITOR | 2518 | #ifdef CONFIG_PROC_PAGE_MONITOR |
2500 | REG("clear_refs", S_IWUSR, clear_refs), | 2519 | REG("clear_refs", S_IWUSR, proc_clear_refs_operations), |
2501 | REG("smaps", S_IRUGO, smaps), | 2520 | REG("smaps", S_IRUGO, proc_smaps_operations), |
2502 | REG("pagemap", S_IRUSR, pagemap), | 2521 | REG("pagemap", S_IRUSR, proc_pagemap_operations), |
2503 | #endif | 2522 | #endif |
2504 | #ifdef CONFIG_SECURITY | 2523 | #ifdef CONFIG_SECURITY |
2505 | DIR("attr", S_IRUGO|S_IXUGO, attr_dir), | 2524 | DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), |
2506 | #endif | 2525 | #endif |
2507 | #ifdef CONFIG_KALLSYMS | 2526 | #ifdef CONFIG_KALLSYMS |
2508 | INF("wchan", S_IRUGO, pid_wchan), | 2527 | INF("wchan", S_IRUGO, proc_pid_wchan), |
2528 | #endif | ||
2529 | #ifdef CONFIG_STACKTRACE | ||
2530 | ONE("stack", S_IRUSR, proc_pid_stack), | ||
2509 | #endif | 2531 | #endif |
2510 | #ifdef CONFIG_SCHEDSTATS | 2532 | #ifdef CONFIG_SCHEDSTATS |
2511 | INF("schedstat", S_IRUGO, pid_schedstat), | 2533 | INF("schedstat", S_IRUGO, proc_pid_schedstat), |
2512 | #endif | 2534 | #endif |
2513 | #ifdef CONFIG_LATENCYTOP | 2535 | #ifdef CONFIG_LATENCYTOP |
2514 | REG("latency", S_IRUGO, lstats), | 2536 | REG("latency", S_IRUGO, proc_lstats_operations), |
2515 | #endif | 2537 | #endif |
2516 | #ifdef CONFIG_PROC_PID_CPUSET | 2538 | #ifdef CONFIG_PROC_PID_CPUSET |
2517 | REG("cpuset", S_IRUGO, cpuset), | 2539 | REG("cpuset", S_IRUGO, proc_cpuset_operations), |
2518 | #endif | 2540 | #endif |
2519 | #ifdef CONFIG_CGROUPS | 2541 | #ifdef CONFIG_CGROUPS |
2520 | REG("cgroup", S_IRUGO, cgroup), | 2542 | REG("cgroup", S_IRUGO, proc_cgroup_operations), |
2521 | #endif | 2543 | #endif |
2522 | INF("oom_score", S_IRUGO, oom_score), | 2544 | INF("oom_score", S_IRUGO, proc_oom_score), |
2523 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), | 2545 | REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations), |
2524 | #ifdef CONFIG_AUDITSYSCALL | 2546 | #ifdef CONFIG_AUDITSYSCALL |
2525 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2547 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), |
2526 | REG("sessionid", S_IRUGO, sessionid), | 2548 | REG("sessionid", S_IRUGO, proc_sessionid_operations), |
2527 | #endif | 2549 | #endif |
2528 | #ifdef CONFIG_FAULT_INJECTION | 2550 | #ifdef CONFIG_FAULT_INJECTION |
2529 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | 2551 | REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), |
2530 | #endif | 2552 | #endif |
2531 | #if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) | 2553 | #if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) |
2532 | REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter), | 2554 | REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), |
2533 | #endif | 2555 | #endif |
2534 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2556 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2535 | INF("io", S_IRUGO, tgid_io_accounting), | 2557 | INF("io", S_IRUGO, proc_tgid_io_accounting), |
2536 | #endif | 2558 | #endif |
2537 | }; | 2559 | }; |
2538 | 2560 | ||
@@ -2805,66 +2827,69 @@ out_no_task: | |||
2805 | * Tasks | 2827 | * Tasks |
2806 | */ | 2828 | */ |
2807 | static const struct pid_entry tid_base_stuff[] = { | 2829 | static const struct pid_entry tid_base_stuff[] = { |
2808 | DIR("fd", S_IRUSR|S_IXUSR, fd), | 2830 | DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), |
2809 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | 2831 | DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations), |
2810 | REG("environ", S_IRUSR, environ), | 2832 | REG("environ", S_IRUSR, proc_environ_operations), |
2811 | INF("auxv", S_IRUSR, pid_auxv), | 2833 | INF("auxv", S_IRUSR, proc_pid_auxv), |
2812 | ONE("status", S_IRUGO, pid_status), | 2834 | ONE("status", S_IRUGO, proc_pid_status), |
2813 | ONE("personality", S_IRUSR, pid_personality), | 2835 | ONE("personality", S_IRUSR, proc_pid_personality), |
2814 | INF("limits", S_IRUSR, pid_limits), | 2836 | INF("limits", S_IRUSR, proc_pid_limits), |
2815 | #ifdef CONFIG_SCHED_DEBUG | 2837 | #ifdef CONFIG_SCHED_DEBUG |
2816 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2838 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2817 | #endif | 2839 | #endif |
2818 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2840 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2819 | INF("syscall", S_IRUSR, pid_syscall), | 2841 | INF("syscall", S_IRUSR, proc_pid_syscall), |
2820 | #endif | 2842 | #endif |
2821 | INF("cmdline", S_IRUGO, pid_cmdline), | 2843 | INF("cmdline", S_IRUGO, proc_pid_cmdline), |
2822 | ONE("stat", S_IRUGO, tid_stat), | 2844 | ONE("stat", S_IRUGO, proc_tid_stat), |
2823 | ONE("statm", S_IRUGO, pid_statm), | 2845 | ONE("statm", S_IRUGO, proc_pid_statm), |
2824 | REG("maps", S_IRUGO, maps), | 2846 | REG("maps", S_IRUGO, proc_maps_operations), |
2825 | #ifdef CONFIG_NUMA | 2847 | #ifdef CONFIG_NUMA |
2826 | REG("numa_maps", S_IRUGO, numa_maps), | 2848 | REG("numa_maps", S_IRUGO, proc_numa_maps_operations), |
2827 | #endif | 2849 | #endif |
2828 | REG("mem", S_IRUSR|S_IWUSR, mem), | 2850 | REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations), |
2829 | LNK("cwd", cwd), | 2851 | LNK("cwd", proc_cwd_link), |
2830 | LNK("root", root), | 2852 | LNK("root", proc_root_link), |
2831 | LNK("exe", exe), | 2853 | LNK("exe", proc_exe_link), |
2832 | REG("mounts", S_IRUGO, mounts), | 2854 | REG("mounts", S_IRUGO, proc_mounts_operations), |
2833 | REG("mountinfo", S_IRUGO, mountinfo), | 2855 | REG("mountinfo", S_IRUGO, proc_mountinfo_operations), |
2834 | #ifdef CONFIG_PROC_PAGE_MONITOR | 2856 | #ifdef CONFIG_PROC_PAGE_MONITOR |
2835 | REG("clear_refs", S_IWUSR, clear_refs), | 2857 | REG("clear_refs", S_IWUSR, proc_clear_refs_operations), |
2836 | REG("smaps", S_IRUGO, smaps), | 2858 | REG("smaps", S_IRUGO, proc_smaps_operations), |
2837 | REG("pagemap", S_IRUSR, pagemap), | 2859 | REG("pagemap", S_IRUSR, proc_pagemap_operations), |
2838 | #endif | 2860 | #endif |
2839 | #ifdef CONFIG_SECURITY | 2861 | #ifdef CONFIG_SECURITY |
2840 | DIR("attr", S_IRUGO|S_IXUGO, attr_dir), | 2862 | DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), |
2841 | #endif | 2863 | #endif |
2842 | #ifdef CONFIG_KALLSYMS | 2864 | #ifdef CONFIG_KALLSYMS |
2843 | INF("wchan", S_IRUGO, pid_wchan), | 2865 | INF("wchan", S_IRUGO, proc_pid_wchan), |
2866 | #endif | ||
2867 | #ifdef CONFIG_STACKTRACE | ||
2868 | ONE("stack", S_IRUSR, proc_pid_stack), | ||
2844 | #endif | 2869 | #endif |
2845 | #ifdef CONFIG_SCHEDSTATS | 2870 | #ifdef CONFIG_SCHEDSTATS |
2846 | INF("schedstat", S_IRUGO, pid_schedstat), | 2871 | INF("schedstat", S_IRUGO, proc_pid_schedstat), |
2847 | #endif | 2872 | #endif |
2848 | #ifdef CONFIG_LATENCYTOP | 2873 | #ifdef CONFIG_LATENCYTOP |
2849 | REG("latency", S_IRUGO, lstats), | 2874 | REG("latency", S_IRUGO, proc_lstats_operations), |
2850 | #endif | 2875 | #endif |
2851 | #ifdef CONFIG_PROC_PID_CPUSET | 2876 | #ifdef CONFIG_PROC_PID_CPUSET |
2852 | REG("cpuset", S_IRUGO, cpuset), | 2877 | REG("cpuset", S_IRUGO, proc_cpuset_operations), |
2853 | #endif | 2878 | #endif |
2854 | #ifdef CONFIG_CGROUPS | 2879 | #ifdef CONFIG_CGROUPS |
2855 | REG("cgroup", S_IRUGO, cgroup), | 2880 | REG("cgroup", S_IRUGO, proc_cgroup_operations), |
2856 | #endif | 2881 | #endif |
2857 | INF("oom_score", S_IRUGO, oom_score), | 2882 | INF("oom_score", S_IRUGO, proc_oom_score), |
2858 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), | 2883 | REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations), |
2859 | #ifdef CONFIG_AUDITSYSCALL | 2884 | #ifdef CONFIG_AUDITSYSCALL |
2860 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2885 | REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), |
2861 | REG("sessionid", S_IRUSR, sessionid), | 2886 | REG("sessionid", S_IRUSR, proc_sessionid_operations), |
2862 | #endif | 2887 | #endif |
2863 | #ifdef CONFIG_FAULT_INJECTION | 2888 | #ifdef CONFIG_FAULT_INJECTION |
2864 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | 2889 | REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), |
2865 | #endif | 2890 | #endif |
2866 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2891 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2867 | INF("io", S_IRUGO, tid_io_accounting), | 2892 | INF("io", S_IRUGO, proc_tid_io_accounting), |
2868 | #endif | 2893 | #endif |
2869 | }; | 2894 | }; |
2870 | 2895 | ||
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 60a359b35582..db7fa5cab988 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/mount.h> | 16 | #include <linux/mount.h> |
17 | #include <linux/smp_lock.h> | ||
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/idr.h> | 18 | #include <linux/idr.h> |
20 | #include <linux/namei.h> | 19 | #include <linux/namei.h> |
@@ -379,7 +378,6 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
379 | struct inode *inode = NULL; | 378 | struct inode *inode = NULL; |
380 | int error = -ENOENT; | 379 | int error = -ENOENT; |
381 | 380 | ||
382 | lock_kernel(); | ||
383 | spin_lock(&proc_subdir_lock); | 381 | spin_lock(&proc_subdir_lock); |
384 | for (de = de->subdir; de ; de = de->next) { | 382 | for (de = de->subdir; de ; de = de->next) { |
385 | if (de->namelen != dentry->d_name.len) | 383 | if (de->namelen != dentry->d_name.len) |
@@ -397,7 +395,6 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
397 | } | 395 | } |
398 | spin_unlock(&proc_subdir_lock); | 396 | spin_unlock(&proc_subdir_lock); |
399 | out_unlock: | 397 | out_unlock: |
400 | unlock_kernel(); | ||
401 | 398 | ||
402 | if (inode) { | 399 | if (inode) { |
403 | dentry->d_op = &proc_dentry_operations; | 400 | dentry->d_op = &proc_dentry_operations; |
@@ -432,8 +429,6 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, | |||
432 | struct inode *inode = filp->f_path.dentry->d_inode; | 429 | struct inode *inode = filp->f_path.dentry->d_inode; |
433 | int ret = 0; | 430 | int ret = 0; |
434 | 431 | ||
435 | lock_kernel(); | ||
436 | |||
437 | ino = inode->i_ino; | 432 | ino = inode->i_ino; |
438 | i = filp->f_pos; | 433 | i = filp->f_pos; |
439 | switch (i) { | 434 | switch (i) { |
@@ -487,7 +482,7 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, | |||
487 | spin_unlock(&proc_subdir_lock); | 482 | spin_unlock(&proc_subdir_lock); |
488 | } | 483 | } |
489 | ret = 1; | 484 | ret = 1; |
490 | out: unlock_kernel(); | 485 | out: |
491 | return ret; | 486 | return ret; |
492 | } | 487 | } |
493 | 488 | ||
@@ -504,6 +499,7 @@ int proc_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
504 | * the /proc directory. | 499 | * the /proc directory. |
505 | */ | 500 | */ |
506 | static const struct file_operations proc_dir_operations = { | 501 | static const struct file_operations proc_dir_operations = { |
502 | .llseek = generic_file_llseek, | ||
507 | .read = generic_read_dir, | 503 | .read = generic_read_dir, |
508 | .readdir = proc_readdir, | 504 | .readdir = proc_readdir, |
509 | }; | 505 | }; |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 2543fd00c658..3e76bb9b3ad6 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -35,16 +35,13 @@ struct proc_dir_entry *de_get(struct proc_dir_entry *de) | |||
35 | */ | 35 | */ |
36 | void de_put(struct proc_dir_entry *de) | 36 | void de_put(struct proc_dir_entry *de) |
37 | { | 37 | { |
38 | lock_kernel(); | ||
39 | if (!atomic_read(&de->count)) { | 38 | if (!atomic_read(&de->count)) { |
40 | printk("de_put: entry %s already free!\n", de->name); | 39 | printk("de_put: entry %s already free!\n", de->name); |
41 | unlock_kernel(); | ||
42 | return; | 40 | return; |
43 | } | 41 | } |
44 | 42 | ||
45 | if (atomic_dec_and_test(&de->count)) | 43 | if (atomic_dec_and_test(&de->count)) |
46 | free_proc_entry(de); | 44 | free_proc_entry(de); |
47 | unlock_kernel(); | ||
48 | } | 45 | } |
49 | 46 | ||
50 | /* | 47 | /* |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 3e8aeb8b61ce..cd53ff838498 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -41,8 +41,6 @@ do { \ | |||
41 | (vmi)->used = 0; \ | 41 | (vmi)->used = 0; \ |
42 | (vmi)->largest_chunk = 0; \ | 42 | (vmi)->largest_chunk = 0; \ |
43 | } while(0) | 43 | } while(0) |
44 | |||
45 | extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *); | ||
46 | #endif | 44 | #endif |
47 | 45 | ||
48 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, | 46 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index b1675c4e66da..43d23948384a 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -74,6 +74,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
74 | "LowTotal: %8lu kB\n" | 74 | "LowTotal: %8lu kB\n" |
75 | "LowFree: %8lu kB\n" | 75 | "LowFree: %8lu kB\n" |
76 | #endif | 76 | #endif |
77 | #ifndef CONFIG_MMU | ||
78 | "MmapCopy: %8lu kB\n" | ||
79 | #endif | ||
77 | "SwapTotal: %8lu kB\n" | 80 | "SwapTotal: %8lu kB\n" |
78 | "SwapFree: %8lu kB\n" | 81 | "SwapFree: %8lu kB\n" |
79 | "Dirty: %8lu kB\n" | 82 | "Dirty: %8lu kB\n" |
@@ -116,6 +119,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
116 | K(i.totalram-i.totalhigh), | 119 | K(i.totalram-i.totalhigh), |
117 | K(i.freeram-i.freehigh), | 120 | K(i.freeram-i.freehigh), |
118 | #endif | 121 | #endif |
122 | #ifndef CONFIG_MMU | ||
123 | K((unsigned long) atomic_read(&mmap_pages_allocated)), | ||
124 | #endif | ||
119 | K(i.totalswap), | 125 | K(i.totalswap), |
120 | K(i.freeswap), | 126 | K(i.freeswap), |
121 | K(global_page_state(NR_FILE_DIRTY)), | 127 | K(global_page_state(NR_FILE_DIRTY)), |
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c index 3f87d2632947..b446d7ad0b0d 100644 --- a/fs/proc/nommu.c +++ b/fs/proc/nommu.c | |||
@@ -33,33 +33,33 @@ | |||
33 | #include "internal.h" | 33 | #include "internal.h" |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * display a single VMA to a sequenced file | 36 | * display a single region to a sequenced file |
37 | */ | 37 | */ |
38 | int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | 38 | static int nommu_region_show(struct seq_file *m, struct vm_region *region) |
39 | { | 39 | { |
40 | unsigned long ino = 0; | 40 | unsigned long ino = 0; |
41 | struct file *file; | 41 | struct file *file; |
42 | dev_t dev = 0; | 42 | dev_t dev = 0; |
43 | int flags, len; | 43 | int flags, len; |
44 | 44 | ||
45 | flags = vma->vm_flags; | 45 | flags = region->vm_flags; |
46 | file = vma->vm_file; | 46 | file = region->vm_file; |
47 | 47 | ||
48 | if (file) { | 48 | if (file) { |
49 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | 49 | struct inode *inode = region->vm_file->f_path.dentry->d_inode; |
50 | dev = inode->i_sb->s_dev; | 50 | dev = inode->i_sb->s_dev; |
51 | ino = inode->i_ino; | 51 | ino = inode->i_ino; |
52 | } | 52 | } |
53 | 53 | ||
54 | seq_printf(m, | 54 | seq_printf(m, |
55 | "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", | 55 | "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", |
56 | vma->vm_start, | 56 | region->vm_start, |
57 | vma->vm_end, | 57 | region->vm_end, |
58 | flags & VM_READ ? 'r' : '-', | 58 | flags & VM_READ ? 'r' : '-', |
59 | flags & VM_WRITE ? 'w' : '-', | 59 | flags & VM_WRITE ? 'w' : '-', |
60 | flags & VM_EXEC ? 'x' : '-', | 60 | flags & VM_EXEC ? 'x' : '-', |
61 | flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p', | 61 | flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p', |
62 | ((loff_t)vma->vm_pgoff) << PAGE_SHIFT, | 62 | ((loff_t)region->vm_pgoff) << PAGE_SHIFT, |
63 | MAJOR(dev), MINOR(dev), ino, &len); | 63 | MAJOR(dev), MINOR(dev), ino, &len); |
64 | 64 | ||
65 | if (file) { | 65 | if (file) { |
@@ -75,61 +75,54 @@ int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | |||
75 | } | 75 | } |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * display a list of all the VMAs the kernel knows about | 78 | * display a list of all the REGIONs the kernel knows about |
79 | * - nommu kernals have a single flat list | 79 | * - nommu kernals have a single flat list |
80 | */ | 80 | */ |
81 | static int nommu_vma_list_show(struct seq_file *m, void *v) | 81 | static int nommu_region_list_show(struct seq_file *m, void *_p) |
82 | { | 82 | { |
83 | struct vm_area_struct *vma; | 83 | struct rb_node *p = _p; |
84 | 84 | ||
85 | vma = rb_entry((struct rb_node *) v, struct vm_area_struct, vm_rb); | 85 | return nommu_region_show(m, rb_entry(p, struct vm_region, vm_rb)); |
86 | return nommu_vma_show(m, vma); | ||
87 | } | 86 | } |
88 | 87 | ||
89 | static void *nommu_vma_list_start(struct seq_file *m, loff_t *_pos) | 88 | static void *nommu_region_list_start(struct seq_file *m, loff_t *_pos) |
90 | { | 89 | { |
91 | struct rb_node *_rb; | 90 | struct rb_node *p; |
92 | loff_t pos = *_pos; | 91 | loff_t pos = *_pos; |
93 | void *next = NULL; | ||
94 | 92 | ||
95 | down_read(&nommu_vma_sem); | 93 | down_read(&nommu_region_sem); |
96 | 94 | ||
97 | for (_rb = rb_first(&nommu_vma_tree); _rb; _rb = rb_next(_rb)) { | 95 | for (p = rb_first(&nommu_region_tree); p; p = rb_next(p)) |
98 | if (pos == 0) { | 96 | if (pos-- == 0) |
99 | next = _rb; | 97 | return p; |
100 | break; | 98 | return NULL; |
101 | } | ||
102 | pos--; | ||
103 | } | ||
104 | |||
105 | return next; | ||
106 | } | 99 | } |
107 | 100 | ||
108 | static void nommu_vma_list_stop(struct seq_file *m, void *v) | 101 | static void nommu_region_list_stop(struct seq_file *m, void *v) |
109 | { | 102 | { |
110 | up_read(&nommu_vma_sem); | 103 | up_read(&nommu_region_sem); |
111 | } | 104 | } |
112 | 105 | ||
113 | static void *nommu_vma_list_next(struct seq_file *m, void *v, loff_t *pos) | 106 | static void *nommu_region_list_next(struct seq_file *m, void *v, loff_t *pos) |
114 | { | 107 | { |
115 | (*pos)++; | 108 | (*pos)++; |
116 | return rb_next((struct rb_node *) v); | 109 | return rb_next((struct rb_node *) v); |
117 | } | 110 | } |
118 | 111 | ||
119 | static const struct seq_operations proc_nommu_vma_list_seqop = { | 112 | static struct seq_operations proc_nommu_region_list_seqop = { |
120 | .start = nommu_vma_list_start, | 113 | .start = nommu_region_list_start, |
121 | .next = nommu_vma_list_next, | 114 | .next = nommu_region_list_next, |
122 | .stop = nommu_vma_list_stop, | 115 | .stop = nommu_region_list_stop, |
123 | .show = nommu_vma_list_show | 116 | .show = nommu_region_list_show |
124 | }; | 117 | }; |
125 | 118 | ||
126 | static int proc_nommu_vma_list_open(struct inode *inode, struct file *file) | 119 | static int proc_nommu_region_list_open(struct inode *inode, struct file *file) |
127 | { | 120 | { |
128 | return seq_open(file, &proc_nommu_vma_list_seqop); | 121 | return seq_open(file, &proc_nommu_region_list_seqop); |
129 | } | 122 | } |
130 | 123 | ||
131 | static const struct file_operations proc_nommu_vma_list_operations = { | 124 | static const struct file_operations proc_nommu_region_list_operations = { |
132 | .open = proc_nommu_vma_list_open, | 125 | .open = proc_nommu_region_list_open, |
133 | .read = seq_read, | 126 | .read = seq_read, |
134 | .llseek = seq_lseek, | 127 | .llseek = seq_lseek, |
135 | .release = seq_release, | 128 | .release = seq_release, |
@@ -137,7 +130,7 @@ static const struct file_operations proc_nommu_vma_list_operations = { | |||
137 | 130 | ||
138 | static int __init proc_nommu_init(void) | 131 | static int __init proc_nommu_init(void) |
139 | { | 132 | { |
140 | proc_create("maps", S_IRUGO, NULL, &proc_nommu_vma_list_operations); | 133 | proc_create("maps", S_IRUGO, NULL, &proc_nommu_region_list_operations); |
141 | return 0; | 134 | return 0; |
142 | } | 135 | } |
143 | 136 | ||
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 7bc296f424ae..04d1270f1c38 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
23 | #include <linux/nsproxy.h> | 22 | #include <linux/nsproxy.h> |
24 | #include <net/net_namespace.h> | 23 | #include <net/net_namespace.h> |
@@ -172,6 +171,7 @@ static int proc_tgid_net_readdir(struct file *filp, void *dirent, | |||
172 | } | 171 | } |
173 | 172 | ||
174 | const struct file_operations proc_net_operations = { | 173 | const struct file_operations proc_net_operations = { |
174 | .llseek = generic_file_llseek, | ||
175 | .read = generic_read_dir, | 175 | .read = generic_read_dir, |
176 | .readdir = proc_tgid_net_readdir, | 176 | .readdir = proc_tgid_net_readdir, |
177 | }; | 177 | }; |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 06ed10b7da9e..94fcfff6863a 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -31,7 +31,6 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, | |||
31 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 31 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
32 | inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */ | 32 | inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */ |
33 | inode->i_mode = table->mode; | 33 | inode->i_mode = table->mode; |
34 | inode->i_uid = inode->i_gid = 0; | ||
35 | if (!table->child) { | 34 | if (!table->child) { |
36 | inode->i_mode |= S_IFREG; | 35 | inode->i_mode |= S_IFREG; |
37 | inode->i_op = &proc_sys_inode_operations; | 36 | inode->i_op = &proc_sys_inode_operations; |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 7761602af9de..f6299a25594e 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
21 | #include <linux/pid_namespace.h> | 20 | #include <linux/pid_namespace.h> |
22 | 21 | ||
@@ -162,17 +161,12 @@ static int proc_root_readdir(struct file * filp, | |||
162 | unsigned int nr = filp->f_pos; | 161 | unsigned int nr = filp->f_pos; |
163 | int ret; | 162 | int ret; |
164 | 163 | ||
165 | lock_kernel(); | ||
166 | |||
167 | if (nr < FIRST_PROCESS_ENTRY) { | 164 | if (nr < FIRST_PROCESS_ENTRY) { |
168 | int error = proc_readdir(filp, dirent, filldir); | 165 | int error = proc_readdir(filp, dirent, filldir); |
169 | if (error <= 0) { | 166 | if (error <= 0) |
170 | unlock_kernel(); | ||
171 | return error; | 167 | return error; |
172 | } | ||
173 | filp->f_pos = FIRST_PROCESS_ENTRY; | 168 | filp->f_pos = FIRST_PROCESS_ENTRY; |
174 | } | 169 | } |
175 | unlock_kernel(); | ||
176 | 170 | ||
177 | ret = proc_pid_readdir(filp, dirent, filldir); | 171 | ret = proc_pid_readdir(filp, dirent, filldir); |
178 | return ret; | 172 | return ret; |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 3bb1cf1e7425..f75efa22df5e 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/seq_file.h> | 9 | #include <linux/seq_file.h> |
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/irqnr.h> | ||
12 | #include <asm/cputime.h> | 13 | #include <asm/cputime.h> |
13 | 14 | ||
14 | #ifndef arch_irq_stat_cpu | 15 | #ifndef arch_irq_stat_cpu |
@@ -45,10 +46,6 @@ static int show_stat(struct seq_file *p, void *v) | |||
45 | steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); | 46 | steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); |
46 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); | 47 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); |
47 | for_each_irq_nr(j) { | 48 | for_each_irq_nr(j) { |
48 | #ifdef CONFIG_SPARSE_IRQ | ||
49 | if (!irq_to_desc(j)) | ||
50 | continue; | ||
51 | #endif | ||
52 | sum += kstat_irqs_cpu(j, i); | 49 | sum += kstat_irqs_cpu(j, i); |
53 | } | 50 | } |
54 | sum += arch_irq_stat_cpu(i); | 51 | sum += arch_irq_stat_cpu(i); |
@@ -95,12 +92,6 @@ static int show_stat(struct seq_file *p, void *v) | |||
95 | /* sum again ? it could be updated? */ | 92 | /* sum again ? it could be updated? */ |
96 | for_each_irq_nr(j) { | 93 | for_each_irq_nr(j) { |
97 | per_irq_sum = 0; | 94 | per_irq_sum = 0; |
98 | #ifdef CONFIG_SPARSE_IRQ | ||
99 | if (!irq_to_desc(j)) { | ||
100 | seq_printf(p, " %u", per_irq_sum); | ||
101 | continue; | ||
102 | } | ||
103 | #endif | ||
104 | for_each_possible_cpu(i) | 95 | for_each_possible_cpu(i) |
105 | per_irq_sum += kstat_irqs_cpu(j, i); | 96 | per_irq_sum += kstat_irqs_cpu(j, i); |
106 | 97 | ||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 3a8bdd7f5756..94063840832a 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -396,7 +396,9 @@ static int show_smap(struct seq_file *m, void *v) | |||
396 | "Private_Clean: %8lu kB\n" | 396 | "Private_Clean: %8lu kB\n" |
397 | "Private_Dirty: %8lu kB\n" | 397 | "Private_Dirty: %8lu kB\n" |
398 | "Referenced: %8lu kB\n" | 398 | "Referenced: %8lu kB\n" |
399 | "Swap: %8lu kB\n", | 399 | "Swap: %8lu kB\n" |
400 | "KernelPageSize: %8lu kB\n" | ||
401 | "MMUPageSize: %8lu kB\n", | ||
400 | (vma->vm_end - vma->vm_start) >> 10, | 402 | (vma->vm_end - vma->vm_start) >> 10, |
401 | mss.resident >> 10, | 403 | mss.resident >> 10, |
402 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), | 404 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), |
@@ -405,7 +407,9 @@ static int show_smap(struct seq_file *m, void *v) | |||
405 | mss.private_clean >> 10, | 407 | mss.private_clean >> 10, |
406 | mss.private_dirty >> 10, | 408 | mss.private_dirty >> 10, |
407 | mss.referenced >> 10, | 409 | mss.referenced >> 10, |
408 | mss.swap >> 10); | 410 | mss.swap >> 10, |
411 | vma_kernel_pagesize(vma) >> 10, | ||
412 | vma_mmu_pagesize(vma) >> 10); | ||
409 | 413 | ||
410 | if (m->count < m->size) /* vma is copied successfully */ | 414 | if (m->count < m->size) /* vma is copied successfully */ |
411 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; | 415 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 219bd79ea894..343ea1216bc8 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -9,31 +9,38 @@ | |||
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Logic: we've got two memory sums for each process, "shared", and | 11 | * Logic: we've got two memory sums for each process, "shared", and |
12 | * "non-shared". Shared memory may get counted more then once, for | 12 | * "non-shared". Shared memory may get counted more than once, for |
13 | * each process that owns it. Non-shared memory is counted | 13 | * each process that owns it. Non-shared memory is counted |
14 | * accurately. | 14 | * accurately. |
15 | */ | 15 | */ |
16 | void task_mem(struct seq_file *m, struct mm_struct *mm) | 16 | void task_mem(struct seq_file *m, struct mm_struct *mm) |
17 | { | 17 | { |
18 | struct vm_list_struct *vml; | 18 | struct vm_area_struct *vma; |
19 | unsigned long bytes = 0, sbytes = 0, slack = 0; | 19 | struct vm_region *region; |
20 | struct rb_node *p; | ||
21 | unsigned long bytes = 0, sbytes = 0, slack = 0, size; | ||
20 | 22 | ||
21 | down_read(&mm->mmap_sem); | 23 | down_read(&mm->mmap_sem); |
22 | for (vml = mm->context.vmlist; vml; vml = vml->next) { | 24 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) { |
23 | if (!vml->vma) | 25 | vma = rb_entry(p, struct vm_area_struct, vm_rb); |
24 | continue; | 26 | |
27 | bytes += kobjsize(vma); | ||
28 | |||
29 | region = vma->vm_region; | ||
30 | if (region) { | ||
31 | size = kobjsize(region); | ||
32 | size += region->vm_end - region->vm_start; | ||
33 | } else { | ||
34 | size = vma->vm_end - vma->vm_start; | ||
35 | } | ||
25 | 36 | ||
26 | bytes += kobjsize(vml); | ||
27 | if (atomic_read(&mm->mm_count) > 1 || | 37 | if (atomic_read(&mm->mm_count) > 1 || |
28 | atomic_read(&vml->vma->vm_usage) > 1 | 38 | vma->vm_flags & VM_MAYSHARE) { |
29 | ) { | 39 | sbytes += size; |
30 | sbytes += kobjsize((void *) vml->vma->vm_start); | ||
31 | sbytes += kobjsize(vml->vma); | ||
32 | } else { | 40 | } else { |
33 | bytes += kobjsize((void *) vml->vma->vm_start); | 41 | bytes += size; |
34 | bytes += kobjsize(vml->vma); | 42 | if (region) |
35 | slack += kobjsize((void *) vml->vma->vm_start) - | 43 | slack = region->vm_end - vma->vm_end; |
36 | (vml->vma->vm_end - vml->vma->vm_start); | ||
37 | } | 44 | } |
38 | } | 45 | } |
39 | 46 | ||
@@ -70,13 +77,14 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) | |||
70 | 77 | ||
71 | unsigned long task_vsize(struct mm_struct *mm) | 78 | unsigned long task_vsize(struct mm_struct *mm) |
72 | { | 79 | { |
73 | struct vm_list_struct *tbp; | 80 | struct vm_area_struct *vma; |
81 | struct rb_node *p; | ||
74 | unsigned long vsize = 0; | 82 | unsigned long vsize = 0; |
75 | 83 | ||
76 | down_read(&mm->mmap_sem); | 84 | down_read(&mm->mmap_sem); |
77 | for (tbp = mm->context.vmlist; tbp; tbp = tbp->next) { | 85 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) { |
78 | if (tbp->vma) | 86 | vma = rb_entry(p, struct vm_area_struct, vm_rb); |
79 | vsize += kobjsize((void *) tbp->vma->vm_start); | 87 | vsize += vma->vm_end - vma->vm_start; |
80 | } | 88 | } |
81 | up_read(&mm->mmap_sem); | 89 | up_read(&mm->mmap_sem); |
82 | return vsize; | 90 | return vsize; |
@@ -85,15 +93,19 @@ unsigned long task_vsize(struct mm_struct *mm) | |||
85 | int task_statm(struct mm_struct *mm, int *shared, int *text, | 93 | int task_statm(struct mm_struct *mm, int *shared, int *text, |
86 | int *data, int *resident) | 94 | int *data, int *resident) |
87 | { | 95 | { |
88 | struct vm_list_struct *tbp; | 96 | struct vm_area_struct *vma; |
97 | struct vm_region *region; | ||
98 | struct rb_node *p; | ||
89 | int size = kobjsize(mm); | 99 | int size = kobjsize(mm); |
90 | 100 | ||
91 | down_read(&mm->mmap_sem); | 101 | down_read(&mm->mmap_sem); |
92 | for (tbp = mm->context.vmlist; tbp; tbp = tbp->next) { | 102 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) { |
93 | size += kobjsize(tbp); | 103 | vma = rb_entry(p, struct vm_area_struct, vm_rb); |
94 | if (tbp->vma) { | 104 | size += kobjsize(vma); |
95 | size += kobjsize(tbp->vma); | 105 | region = vma->vm_region; |
96 | size += kobjsize((void *) tbp->vma->vm_start); | 106 | if (region) { |
107 | size += kobjsize(region); | ||
108 | size += region->vm_end - region->vm_start; | ||
97 | } | 109 | } |
98 | } | 110 | } |
99 | 111 | ||
@@ -105,20 +117,62 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, | |||
105 | } | 117 | } |
106 | 118 | ||
107 | /* | 119 | /* |
120 | * display a single VMA to a sequenced file | ||
121 | */ | ||
122 | static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | ||
123 | { | ||
124 | unsigned long ino = 0; | ||
125 | struct file *file; | ||
126 | dev_t dev = 0; | ||
127 | int flags, len; | ||
128 | |||
129 | flags = vma->vm_flags; | ||
130 | file = vma->vm_file; | ||
131 | |||
132 | if (file) { | ||
133 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | ||
134 | dev = inode->i_sb->s_dev; | ||
135 | ino = inode->i_ino; | ||
136 | } | ||
137 | |||
138 | seq_printf(m, | ||
139 | "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n", | ||
140 | vma->vm_start, | ||
141 | vma->vm_end, | ||
142 | flags & VM_READ ? 'r' : '-', | ||
143 | flags & VM_WRITE ? 'w' : '-', | ||
144 | flags & VM_EXEC ? 'x' : '-', | ||
145 | flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p', | ||
146 | vma->vm_pgoff << PAGE_SHIFT, | ||
147 | MAJOR(dev), MINOR(dev), ino, &len); | ||
148 | |||
149 | if (file) { | ||
150 | len = 25 + sizeof(void *) * 6 - len; | ||
151 | if (len < 1) | ||
152 | len = 1; | ||
153 | seq_printf(m, "%*c", len, ' '); | ||
154 | seq_path(m, &file->f_path, ""); | ||
155 | } | ||
156 | |||
157 | seq_putc(m, '\n'); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* | ||
108 | * display mapping lines for a particular process's /proc/pid/maps | 162 | * display mapping lines for a particular process's /proc/pid/maps |
109 | */ | 163 | */ |
110 | static int show_map(struct seq_file *m, void *_vml) | 164 | static int show_map(struct seq_file *m, void *_p) |
111 | { | 165 | { |
112 | struct vm_list_struct *vml = _vml; | 166 | struct rb_node *p = _p; |
113 | 167 | ||
114 | return nommu_vma_show(m, vml->vma); | 168 | return nommu_vma_show(m, rb_entry(p, struct vm_area_struct, vm_rb)); |
115 | } | 169 | } |
116 | 170 | ||
117 | static void *m_start(struct seq_file *m, loff_t *pos) | 171 | static void *m_start(struct seq_file *m, loff_t *pos) |
118 | { | 172 | { |
119 | struct proc_maps_private *priv = m->private; | 173 | struct proc_maps_private *priv = m->private; |
120 | struct vm_list_struct *vml; | ||
121 | struct mm_struct *mm; | 174 | struct mm_struct *mm; |
175 | struct rb_node *p; | ||
122 | loff_t n = *pos; | 176 | loff_t n = *pos; |
123 | 177 | ||
124 | /* pin the task and mm whilst we play with them */ | 178 | /* pin the task and mm whilst we play with them */ |
@@ -134,9 +188,9 @@ static void *m_start(struct seq_file *m, loff_t *pos) | |||
134 | } | 188 | } |
135 | 189 | ||
136 | /* start from the Nth VMA */ | 190 | /* start from the Nth VMA */ |
137 | for (vml = mm->context.vmlist; vml; vml = vml->next) | 191 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) |
138 | if (n-- == 0) | 192 | if (n-- == 0) |
139 | return vml; | 193 | return p; |
140 | return NULL; | 194 | return NULL; |
141 | } | 195 | } |
142 | 196 | ||
@@ -152,12 +206,12 @@ static void m_stop(struct seq_file *m, void *_vml) | |||
152 | } | 206 | } |
153 | } | 207 | } |
154 | 208 | ||
155 | static void *m_next(struct seq_file *m, void *_vml, loff_t *pos) | 209 | static void *m_next(struct seq_file *m, void *_p, loff_t *pos) |
156 | { | 210 | { |
157 | struct vm_list_struct *vml = _vml; | 211 | struct rb_node *p = _p; |
158 | 212 | ||
159 | (*pos)++; | 213 | (*pos)++; |
160 | return vml ? vml->next : NULL; | 214 | return p ? rb_next(p) : NULL; |
161 | } | 215 | } |
162 | 216 | ||
163 | static const struct seq_operations proc_pid_maps_ops = { | 217 | static const struct seq_operations proc_pid_maps_ops = { |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 03ec59504906..5edcc3f92ba7 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -47,8 +47,6 @@ static ssize_t read_from_oldmem(char *buf, size_t count, | |||
47 | 47 | ||
48 | offset = (unsigned long)(*ppos % PAGE_SIZE); | 48 | offset = (unsigned long)(*ppos % PAGE_SIZE); |
49 | pfn = (unsigned long)(*ppos / PAGE_SIZE); | 49 | pfn = (unsigned long)(*ppos / PAGE_SIZE); |
50 | if (pfn > saved_max_pfn) | ||
51 | return -EINVAL; | ||
52 | 50 | ||
53 | do { | 51 | do { |
54 | if (count > (PAGE_SIZE - offset)) | 52 | if (count > (PAGE_SIZE - offset)) |