diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/Makefile | 1 | ||||
-rw-r--r-- | fs/proc/array.c | 22 | ||||
-rw-r--r-- | fs/proc/base.c | 89 | ||||
-rw-r--r-- | fs/proc/cmdline.c | 2 | ||||
-rw-r--r-- | fs/proc/consoles.c | 2 | ||||
-rw-r--r-- | fs/proc/cpuinfo.c | 2 | ||||
-rw-r--r-- | fs/proc/devices.c | 2 | ||||
-rw-r--r-- | fs/proc/fd.c | 6 | ||||
-rw-r--r-- | fs/proc/generic.c | 3 | ||||
-rw-r--r-- | fs/proc/inode.c | 4 | ||||
-rw-r--r-- | fs/proc/internal.h | 7 | ||||
-rw-r--r-- | fs/proc/interrupts.c | 2 | ||||
-rw-r--r-- | fs/proc/kcore.c | 2 | ||||
-rw-r--r-- | fs/proc/kmsg.c | 2 | ||||
-rw-r--r-- | fs/proc/loadavg.c | 2 | ||||
-rw-r--r-- | fs/proc/meminfo.c | 39 | ||||
-rw-r--r-- | fs/proc/nommu.c | 2 | ||||
-rw-r--r-- | fs/proc/page.c | 9 | ||||
-rw-r--r-- | fs/proc/proc_devtree.c | 240 | ||||
-rw-r--r-- | fs/proc/root.c | 5 | ||||
-rw-r--r-- | fs/proc/softirqs.c | 2 | ||||
-rw-r--r-- | fs/proc/stat.c | 4 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 3 | ||||
-rw-r--r-- | fs/proc/uptime.c | 4 | ||||
-rw-r--r-- | fs/proc/version.c | 2 | ||||
-rw-r--r-- | fs/proc/vmcore.c | 27 |
26 files changed, 142 insertions, 343 deletions
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index ab30716584f5..239493ec718e 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -27,6 +27,5 @@ proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o | |||
27 | proc-$(CONFIG_NET) += proc_net.o | 27 | proc-$(CONFIG_NET) += proc_net.o |
28 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 28 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
29 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | 29 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o |
30 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | ||
31 | proc-$(CONFIG_PRINTK) += kmsg.o | 30 | proc-$(CONFIG_PRINTK) += kmsg.o |
32 | proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o | 31 | proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 1bd2077187fd..64db2bceac59 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -138,26 +138,17 @@ static const char * const task_state_array[] = { | |||
138 | "D (disk sleep)", /* 2 */ | 138 | "D (disk sleep)", /* 2 */ |
139 | "T (stopped)", /* 4 */ | 139 | "T (stopped)", /* 4 */ |
140 | "t (tracing stop)", /* 8 */ | 140 | "t (tracing stop)", /* 8 */ |
141 | "Z (zombie)", /* 16 */ | 141 | "X (dead)", /* 16 */ |
142 | "X (dead)", /* 32 */ | 142 | "Z (zombie)", /* 32 */ |
143 | "x (dead)", /* 64 */ | ||
144 | "K (wakekill)", /* 128 */ | ||
145 | "W (waking)", /* 256 */ | ||
146 | "P (parked)", /* 512 */ | ||
147 | }; | 143 | }; |
148 | 144 | ||
149 | static inline const char *get_task_state(struct task_struct *tsk) | 145 | static inline const char *get_task_state(struct task_struct *tsk) |
150 | { | 146 | { |
151 | unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state; | 147 | unsigned int state = (tsk->state | tsk->exit_state) & TASK_REPORT; |
152 | const char * const *p = &task_state_array[0]; | ||
153 | 148 | ||
154 | BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array)); | 149 | BUILD_BUG_ON(1 + ilog2(TASK_REPORT) != ARRAY_SIZE(task_state_array)-1); |
155 | 150 | ||
156 | while (state) { | 151 | return task_state_array[fls(state)]; |
157 | p++; | ||
158 | state >>= 1; | ||
159 | } | ||
160 | return *p; | ||
161 | } | 152 | } |
162 | 153 | ||
163 | static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | 154 | static inline void task_state(struct seq_file *m, struct pid_namespace *ns, |
@@ -453,8 +444,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
453 | min_flt += t->min_flt; | 444 | min_flt += t->min_flt; |
454 | maj_flt += t->maj_flt; | 445 | maj_flt += t->maj_flt; |
455 | gtime += task_gtime(t); | 446 | gtime += task_gtime(t); |
456 | t = next_thread(t); | 447 | } while_each_thread(task, t); |
457 | } while (t != task); | ||
458 | 448 | ||
459 | min_flt += sig->min_flt; | 449 | min_flt += sig->min_flt; |
460 | maj_flt += sig->maj_flt; | 450 | maj_flt += sig->maj_flt; |
diff --git a/fs/proc/base.c b/fs/proc/base.c index cfd178dc76b2..2d696b0c93bf 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1204,6 +1204,9 @@ static ssize_t proc_fault_inject_write(struct file * file, | |||
1204 | make_it_fail = simple_strtol(strstrip(buffer), &end, 0); | 1204 | make_it_fail = simple_strtol(strstrip(buffer), &end, 0); |
1205 | if (*end) | 1205 | if (*end) |
1206 | return -EINVAL; | 1206 | return -EINVAL; |
1207 | if (make_it_fail < 0 || make_it_fail > 1) | ||
1208 | return -EINVAL; | ||
1209 | |||
1207 | task = get_proc_task(file_inode(file)); | 1210 | task = get_proc_task(file_inode(file)); |
1208 | if (!task) | 1211 | if (!task) |
1209 | return -ESRCH; | 1212 | return -ESRCH; |
@@ -1626,13 +1629,18 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags) | |||
1626 | return 0; | 1629 | return 0; |
1627 | } | 1630 | } |
1628 | 1631 | ||
1632 | static inline bool proc_inode_is_dead(struct inode *inode) | ||
1633 | { | ||
1634 | return !proc_pid(inode)->tasks[PIDTYPE_PID].first; | ||
1635 | } | ||
1636 | |||
1629 | int pid_delete_dentry(const struct dentry *dentry) | 1637 | int pid_delete_dentry(const struct dentry *dentry) |
1630 | { | 1638 | { |
1631 | /* Is the task we represent dead? | 1639 | /* Is the task we represent dead? |
1632 | * If so, then don't put the dentry on the lru list, | 1640 | * If so, then don't put the dentry on the lru list, |
1633 | * kill it immediately. | 1641 | * kill it immediately. |
1634 | */ | 1642 | */ |
1635 | return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; | 1643 | return proc_inode_is_dead(dentry->d_inode); |
1636 | } | 1644 | } |
1637 | 1645 | ||
1638 | const struct dentry_operations pid_dentry_operations = | 1646 | const struct dentry_operations pid_dentry_operations = |
@@ -1787,6 +1795,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) | |||
1787 | if (rc) | 1795 | if (rc) |
1788 | goto out_mmput; | 1796 | goto out_mmput; |
1789 | 1797 | ||
1798 | rc = -ENOENT; | ||
1790 | down_read(&mm->mmap_sem); | 1799 | down_read(&mm->mmap_sem); |
1791 | vma = find_exact_vma(mm, vm_start, vm_end); | 1800 | vma = find_exact_vma(mm, vm_start, vm_end); |
1792 | if (vma && vma->vm_file) { | 1801 | if (vma && vma->vm_file) { |
@@ -2550,7 +2559,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2550 | REG("environ", S_IRUSR, proc_environ_operations), | 2559 | REG("environ", S_IRUSR, proc_environ_operations), |
2551 | INF("auxv", S_IRUSR, proc_pid_auxv), | 2560 | INF("auxv", S_IRUSR, proc_pid_auxv), |
2552 | ONE("status", S_IRUGO, proc_pid_status), | 2561 | ONE("status", S_IRUGO, proc_pid_status), |
2553 | ONE("personality", S_IRUGO, proc_pid_personality), | 2562 | ONE("personality", S_IRUSR, proc_pid_personality), |
2554 | INF("limits", S_IRUGO, proc_pid_limits), | 2563 | INF("limits", S_IRUGO, proc_pid_limits), |
2555 | #ifdef CONFIG_SCHED_DEBUG | 2564 | #ifdef CONFIG_SCHED_DEBUG |
2556 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 2565 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
@@ -2560,7 +2569,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2560 | #endif | 2569 | #endif |
2561 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), | 2570 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), |
2562 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2571 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2563 | INF("syscall", S_IRUGO, proc_pid_syscall), | 2572 | INF("syscall", S_IRUSR, proc_pid_syscall), |
2564 | #endif | 2573 | #endif |
2565 | INF("cmdline", S_IRUGO, proc_pid_cmdline), | 2574 | INF("cmdline", S_IRUGO, proc_pid_cmdline), |
2566 | ONE("stat", S_IRUGO, proc_tgid_stat), | 2575 | ONE("stat", S_IRUGO, proc_tgid_stat), |
@@ -2579,7 +2588,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2579 | #ifdef CONFIG_PROC_PAGE_MONITOR | 2588 | #ifdef CONFIG_PROC_PAGE_MONITOR |
2580 | REG("clear_refs", S_IWUSR, proc_clear_refs_operations), | 2589 | REG("clear_refs", S_IWUSR, proc_clear_refs_operations), |
2581 | REG("smaps", S_IRUGO, proc_pid_smaps_operations), | 2590 | REG("smaps", S_IRUGO, proc_pid_smaps_operations), |
2582 | REG("pagemap", S_IRUGO, proc_pagemap_operations), | 2591 | REG("pagemap", S_IRUSR, proc_pagemap_operations), |
2583 | #endif | 2592 | #endif |
2584 | #ifdef CONFIG_SECURITY | 2593 | #ifdef CONFIG_SECURITY |
2585 | DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), | 2594 | DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), |
@@ -2588,7 +2597,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2588 | INF("wchan", S_IRUGO, proc_pid_wchan), | 2597 | INF("wchan", S_IRUGO, proc_pid_wchan), |
2589 | #endif | 2598 | #endif |
2590 | #ifdef CONFIG_STACKTRACE | 2599 | #ifdef CONFIG_STACKTRACE |
2591 | ONE("stack", S_IRUGO, proc_pid_stack), | 2600 | ONE("stack", S_IRUSR, proc_pid_stack), |
2592 | #endif | 2601 | #endif |
2593 | #ifdef CONFIG_SCHEDSTATS | 2602 | #ifdef CONFIG_SCHEDSTATS |
2594 | INF("schedstat", S_IRUGO, proc_pid_schedstat), | 2603 | INF("schedstat", S_IRUGO, proc_pid_schedstat), |
@@ -2889,14 +2898,14 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2889 | REG("environ", S_IRUSR, proc_environ_operations), | 2898 | REG("environ", S_IRUSR, proc_environ_operations), |
2890 | INF("auxv", S_IRUSR, proc_pid_auxv), | 2899 | INF("auxv", S_IRUSR, proc_pid_auxv), |
2891 | ONE("status", S_IRUGO, proc_pid_status), | 2900 | ONE("status", S_IRUGO, proc_pid_status), |
2892 | ONE("personality", S_IRUGO, proc_pid_personality), | 2901 | ONE("personality", S_IRUSR, proc_pid_personality), |
2893 | INF("limits", S_IRUGO, proc_pid_limits), | 2902 | INF("limits", S_IRUGO, proc_pid_limits), |
2894 | #ifdef CONFIG_SCHED_DEBUG | 2903 | #ifdef CONFIG_SCHED_DEBUG |
2895 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 2904 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2896 | #endif | 2905 | #endif |
2897 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), | 2906 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), |
2898 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2907 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2899 | INF("syscall", S_IRUGO, proc_pid_syscall), | 2908 | INF("syscall", S_IRUSR, proc_pid_syscall), |
2900 | #endif | 2909 | #endif |
2901 | INF("cmdline", S_IRUGO, proc_pid_cmdline), | 2910 | INF("cmdline", S_IRUGO, proc_pid_cmdline), |
2902 | ONE("stat", S_IRUGO, proc_tid_stat), | 2911 | ONE("stat", S_IRUGO, proc_tid_stat), |
@@ -2917,7 +2926,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2917 | #ifdef CONFIG_PROC_PAGE_MONITOR | 2926 | #ifdef CONFIG_PROC_PAGE_MONITOR |
2918 | REG("clear_refs", S_IWUSR, proc_clear_refs_operations), | 2927 | REG("clear_refs", S_IWUSR, proc_clear_refs_operations), |
2919 | REG("smaps", S_IRUGO, proc_tid_smaps_operations), | 2928 | REG("smaps", S_IRUGO, proc_tid_smaps_operations), |
2920 | REG("pagemap", S_IRUGO, proc_pagemap_operations), | 2929 | REG("pagemap", S_IRUSR, proc_pagemap_operations), |
2921 | #endif | 2930 | #endif |
2922 | #ifdef CONFIG_SECURITY | 2931 | #ifdef CONFIG_SECURITY |
2923 | DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), | 2932 | DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), |
@@ -2926,7 +2935,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2926 | INF("wchan", S_IRUGO, proc_pid_wchan), | 2935 | INF("wchan", S_IRUGO, proc_pid_wchan), |
2927 | #endif | 2936 | #endif |
2928 | #ifdef CONFIG_STACKTRACE | 2937 | #ifdef CONFIG_STACKTRACE |
2929 | ONE("stack", S_IRUGO, proc_pid_stack), | 2938 | ONE("stack", S_IRUSR, proc_pid_stack), |
2930 | #endif | 2939 | #endif |
2931 | #ifdef CONFIG_SCHEDSTATS | 2940 | #ifdef CONFIG_SCHEDSTATS |
2932 | INF("schedstat", S_IRUGO, proc_pid_schedstat), | 2941 | INF("schedstat", S_IRUGO, proc_pid_schedstat), |
@@ -3060,34 +3069,42 @@ out_no_task: | |||
3060 | * In the case of a seek we start with the leader and walk nr | 3069 | * In the case of a seek we start with the leader and walk nr |
3061 | * threads past it. | 3070 | * threads past it. |
3062 | */ | 3071 | */ |
3063 | static struct task_struct *first_tid(struct task_struct *leader, | 3072 | static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos, |
3064 | int tid, int nr, struct pid_namespace *ns) | 3073 | struct pid_namespace *ns) |
3065 | { | 3074 | { |
3066 | struct task_struct *pos; | 3075 | struct task_struct *pos, *task; |
3076 | unsigned long nr = f_pos; | ||
3077 | |||
3078 | if (nr != f_pos) /* 32bit overflow? */ | ||
3079 | return NULL; | ||
3067 | 3080 | ||
3068 | rcu_read_lock(); | 3081 | rcu_read_lock(); |
3069 | /* Attempt to start with the pid of a thread */ | 3082 | task = pid_task(pid, PIDTYPE_PID); |
3070 | if (tid && (nr > 0)) { | 3083 | if (!task) |
3084 | goto fail; | ||
3085 | |||
3086 | /* Attempt to start with the tid of a thread */ | ||
3087 | if (tid && nr) { | ||
3071 | pos = find_task_by_pid_ns(tid, ns); | 3088 | pos = find_task_by_pid_ns(tid, ns); |
3072 | if (pos && (pos->group_leader == leader)) | 3089 | if (pos && same_thread_group(pos, task)) |
3073 | goto found; | 3090 | goto found; |
3074 | } | 3091 | } |
3075 | 3092 | ||
3076 | /* If nr exceeds the number of threads there is nothing todo */ | 3093 | /* If nr exceeds the number of threads there is nothing todo */ |
3077 | pos = NULL; | 3094 | if (nr >= get_nr_threads(task)) |
3078 | if (nr && nr >= get_nr_threads(leader)) | 3095 | goto fail; |
3079 | goto out; | ||
3080 | 3096 | ||
3081 | /* If we haven't found our starting place yet start | 3097 | /* If we haven't found our starting place yet start |
3082 | * with the leader and walk nr threads forward. | 3098 | * with the leader and walk nr threads forward. |
3083 | */ | 3099 | */ |
3084 | for (pos = leader; nr > 0; --nr) { | 3100 | pos = task = task->group_leader; |
3085 | pos = next_thread(pos); | 3101 | do { |
3086 | if (pos == leader) { | 3102 | if (!nr--) |
3087 | pos = NULL; | 3103 | goto found; |
3088 | goto out; | 3104 | } while_each_thread(task, pos); |
3089 | } | 3105 | fail: |
3090 | } | 3106 | pos = NULL; |
3107 | goto out; | ||
3091 | found: | 3108 | found: |
3092 | get_task_struct(pos); | 3109 | get_task_struct(pos); |
3093 | out: | 3110 | out: |
@@ -3120,25 +3137,16 @@ static struct task_struct *next_tid(struct task_struct *start) | |||
3120 | /* for the /proc/TGID/task/ directories */ | 3137 | /* for the /proc/TGID/task/ directories */ |
3121 | static int proc_task_readdir(struct file *file, struct dir_context *ctx) | 3138 | static int proc_task_readdir(struct file *file, struct dir_context *ctx) |
3122 | { | 3139 | { |
3123 | struct task_struct *leader = NULL; | 3140 | struct inode *inode = file_inode(file); |
3124 | struct task_struct *task = get_proc_task(file_inode(file)); | 3141 | struct task_struct *task; |
3125 | struct pid_namespace *ns; | 3142 | struct pid_namespace *ns; |
3126 | int tid; | 3143 | int tid; |
3127 | 3144 | ||
3128 | if (!task) | 3145 | if (proc_inode_is_dead(inode)) |
3129 | return -ENOENT; | ||
3130 | rcu_read_lock(); | ||
3131 | if (pid_alive(task)) { | ||
3132 | leader = task->group_leader; | ||
3133 | get_task_struct(leader); | ||
3134 | } | ||
3135 | rcu_read_unlock(); | ||
3136 | put_task_struct(task); | ||
3137 | if (!leader) | ||
3138 | return -ENOENT; | 3146 | return -ENOENT; |
3139 | 3147 | ||
3140 | if (!dir_emit_dots(file, ctx)) | 3148 | if (!dir_emit_dots(file, ctx)) |
3141 | goto out; | 3149 | return 0; |
3142 | 3150 | ||
3143 | /* f_version caches the tgid value that the last readdir call couldn't | 3151 | /* f_version caches the tgid value that the last readdir call couldn't |
3144 | * return. lseek aka telldir automagically resets f_version to 0. | 3152 | * return. lseek aka telldir automagically resets f_version to 0. |
@@ -3146,7 +3154,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx) | |||
3146 | ns = file->f_dentry->d_sb->s_fs_info; | 3154 | ns = file->f_dentry->d_sb->s_fs_info; |
3147 | tid = (int)file->f_version; | 3155 | tid = (int)file->f_version; |
3148 | file->f_version = 0; | 3156 | file->f_version = 0; |
3149 | for (task = first_tid(leader, tid, ctx->pos - 2, ns); | 3157 | for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns); |
3150 | task; | 3158 | task; |
3151 | task = next_tid(task), ctx->pos++) { | 3159 | task = next_tid(task), ctx->pos++) { |
3152 | char name[PROC_NUMBUF]; | 3160 | char name[PROC_NUMBUF]; |
@@ -3162,8 +3170,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx) | |||
3162 | break; | 3170 | break; |
3163 | } | 3171 | } |
3164 | } | 3172 | } |
3165 | out: | 3173 | |
3166 | put_task_struct(leader); | ||
3167 | return 0; | 3174 | return 0; |
3168 | } | 3175 | } |
3169 | 3176 | ||
diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c index 82676e3fcd1d..cbd82dff7e81 100644 --- a/fs/proc/cmdline.c +++ b/fs/proc/cmdline.c | |||
@@ -26,4 +26,4 @@ static int __init proc_cmdline_init(void) | |||
26 | proc_create("cmdline", 0, NULL, &cmdline_proc_fops); | 26 | proc_create("cmdline", 0, NULL, &cmdline_proc_fops); |
27 | return 0; | 27 | return 0; |
28 | } | 28 | } |
29 | module_init(proc_cmdline_init); | 29 | fs_initcall(proc_cmdline_init); |
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c index 51942d5abcec..290ba85cb900 100644 --- a/fs/proc/consoles.c +++ b/fs/proc/consoles.c | |||
@@ -109,4 +109,4 @@ static int __init proc_consoles_init(void) | |||
109 | proc_create("consoles", 0, NULL, &proc_consoles_operations); | 109 | proc_create("consoles", 0, NULL, &proc_consoles_operations); |
110 | return 0; | 110 | return 0; |
111 | } | 111 | } |
112 | module_init(proc_consoles_init); | 112 | fs_initcall(proc_consoles_init); |
diff --git a/fs/proc/cpuinfo.c b/fs/proc/cpuinfo.c index 5a1e539a234b..06f4d31e0396 100644 --- a/fs/proc/cpuinfo.c +++ b/fs/proc/cpuinfo.c | |||
@@ -21,4 +21,4 @@ static int __init proc_cpuinfo_init(void) | |||
21 | proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations); | 21 | proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations); |
22 | return 0; | 22 | return 0; |
23 | } | 23 | } |
24 | module_init(proc_cpuinfo_init); | 24 | fs_initcall(proc_cpuinfo_init); |
diff --git a/fs/proc/devices.c b/fs/proc/devices.c index b14347167c35..50493edc30e5 100644 --- a/fs/proc/devices.c +++ b/fs/proc/devices.c | |||
@@ -67,4 +67,4 @@ static int __init proc_devices_init(void) | |||
67 | proc_create("devices", 0, NULL, &proc_devinfo_operations); | 67 | proc_create("devices", 0, NULL, &proc_devinfo_operations); |
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | module_init(proc_devices_init); | 70 | fs_initcall(proc_devices_init); |
diff --git a/fs/proc/fd.c b/fs/proc/fd.c index 985ea881b5bc..0788d093f5d8 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/proc_fs.h> | 12 | #include <linux/proc_fs.h> |
13 | 13 | ||
14 | #include "../mount.h" | ||
14 | #include "internal.h" | 15 | #include "internal.h" |
15 | #include "fd.h" | 16 | #include "fd.h" |
16 | 17 | ||
@@ -48,8 +49,9 @@ static int seq_show(struct seq_file *m, void *v) | |||
48 | } | 49 | } |
49 | 50 | ||
50 | if (!ret) { | 51 | if (!ret) { |
51 | seq_printf(m, "pos:\t%lli\nflags:\t0%o\n", | 52 | seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n", |
52 | (long long)file->f_pos, f_flags); | 53 | (long long)file->f_pos, f_flags, |
54 | real_mount(file->f_path.mnt)->mnt_id); | ||
53 | if (file->f_op->show_fdinfo) | 55 | if (file->f_op->show_fdinfo) |
54 | ret = file->f_op->show_fdinfo(m, file); | 56 | ret = file->f_op->show_fdinfo(m, file); |
55 | fput(file); | 57 | fput(file); |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index cca93b6fb9a9..b7f268eb5f45 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -49,8 +49,7 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) | |||
49 | setattr_copy(inode, iattr); | 49 | setattr_copy(inode, iattr); |
50 | mark_inode_dirty(inode); | 50 | mark_inode_dirty(inode); |
51 | 51 | ||
52 | de->uid = inode->i_uid; | 52 | proc_set_user(de, inode->i_uid, inode->i_gid); |
53 | de->gid = inode->i_gid; | ||
54 | de->mode = inode->i_mode; | 53 | de->mode = inode->i_mode; |
55 | return 0; | 54 | return 0; |
56 | } | 55 | } |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 124fc43c7090..0adbc02d60e3 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -35,7 +35,7 @@ static void proc_evict_inode(struct inode *inode) | |||
35 | const struct proc_ns_operations *ns_ops; | 35 | const struct proc_ns_operations *ns_ops; |
36 | void *ns; | 36 | void *ns; |
37 | 37 | ||
38 | truncate_inode_pages(&inode->i_data, 0); | 38 | truncate_inode_pages_final(&inode->i_data); |
39 | clear_inode(inode); | 39 | clear_inode(inode); |
40 | 40 | ||
41 | /* Stop tracking associated processes */ | 41 | /* Stop tracking associated processes */ |
@@ -47,7 +47,7 @@ static void proc_evict_inode(struct inode *inode) | |||
47 | pde_put(de); | 47 | pde_put(de); |
48 | head = PROC_I(inode)->sysctl; | 48 | head = PROC_I(inode)->sysctl; |
49 | if (head) { | 49 | if (head) { |
50 | rcu_assign_pointer(PROC_I(inode)->sysctl, NULL); | 50 | RCU_INIT_POINTER(PROC_I(inode)->sysctl, NULL); |
51 | sysctl_head_put(head); | 51 | sysctl_head_put(head); |
52 | } | 52 | } |
53 | /* Release any associated namespace */ | 53 | /* Release any associated namespace */ |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 651d09a11dde..3ab6d14e71c5 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -211,13 +211,6 @@ extern int proc_fill_super(struct super_block *); | |||
211 | extern void proc_entry_rundown(struct proc_dir_entry *); | 211 | extern void proc_entry_rundown(struct proc_dir_entry *); |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * proc_devtree.c | ||
215 | */ | ||
216 | #ifdef CONFIG_PROC_DEVICETREE | ||
217 | extern void proc_device_tree_init(void); | ||
218 | #endif | ||
219 | |||
220 | /* | ||
221 | * proc_namespaces.c | 214 | * proc_namespaces.c |
222 | */ | 215 | */ |
223 | extern const struct inode_operations proc_ns_dir_inode_operations; | 216 | extern const struct inode_operations proc_ns_dir_inode_operations; |
diff --git a/fs/proc/interrupts.c b/fs/proc/interrupts.c index 05029c0e2f24..a352d5703b41 100644 --- a/fs/proc/interrupts.c +++ b/fs/proc/interrupts.c | |||
@@ -50,4 +50,4 @@ static int __init proc_interrupts_init(void) | |||
50 | proc_create("interrupts", 0, NULL, &proc_interrupts_operations); | 50 | proc_create("interrupts", 0, NULL, &proc_interrupts_operations); |
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
53 | module_init(proc_interrupts_init); | 53 | fs_initcall(proc_interrupts_init); |
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 5ed0e52d6aa0..39e6ef32f0bd 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -639,4 +639,4 @@ static int __init proc_kcore_init(void) | |||
639 | 639 | ||
640 | return 0; | 640 | return 0; |
641 | } | 641 | } |
642 | module_init(proc_kcore_init); | 642 | fs_initcall(proc_kcore_init); |
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c index bdfabdaefdce..05f8dcdb086e 100644 --- a/fs/proc/kmsg.c +++ b/fs/proc/kmsg.c | |||
@@ -61,4 +61,4 @@ static int __init proc_kmsg_init(void) | |||
61 | proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations); | 61 | proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations); |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | module_init(proc_kmsg_init); | 64 | fs_initcall(proc_kmsg_init); |
diff --git a/fs/proc/loadavg.c b/fs/proc/loadavg.c index 1afa4dd4cae2..aec66e6c2060 100644 --- a/fs/proc/loadavg.c +++ b/fs/proc/loadavg.c | |||
@@ -42,4 +42,4 @@ static int __init proc_loadavg_init(void) | |||
42 | proc_create("loadavg", 0, NULL, &loadavg_proc_fops); | 42 | proc_create("loadavg", 0, NULL, &loadavg_proc_fops); |
43 | return 0; | 43 | return 0; |
44 | } | 44 | } |
45 | module_init(proc_loadavg_init); | 45 | fs_initcall(proc_loadavg_init); |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index a77d2b299199..7445af0b1aa3 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -26,7 +26,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
26 | unsigned long committed; | 26 | unsigned long committed; |
27 | struct vmalloc_info vmi; | 27 | struct vmalloc_info vmi; |
28 | long cached; | 28 | long cached; |
29 | long available; | ||
30 | unsigned long pagecache; | ||
31 | unsigned long wmark_low = 0; | ||
29 | unsigned long pages[NR_LRU_LISTS]; | 32 | unsigned long pages[NR_LRU_LISTS]; |
33 | struct zone *zone; | ||
30 | int lru; | 34 | int lru; |
31 | 35 | ||
32 | /* | 36 | /* |
@@ -47,12 +51,44 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
47 | for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++) | 51 | for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++) |
48 | pages[lru] = global_page_state(NR_LRU_BASE + lru); | 52 | pages[lru] = global_page_state(NR_LRU_BASE + lru); |
49 | 53 | ||
54 | for_each_zone(zone) | ||
55 | wmark_low += zone->watermark[WMARK_LOW]; | ||
56 | |||
57 | /* | ||
58 | * Estimate the amount of memory available for userspace allocations, | ||
59 | * without causing swapping. | ||
60 | * | ||
61 | * Free memory cannot be taken below the low watermark, before the | ||
62 | * system starts swapping. | ||
63 | */ | ||
64 | available = i.freeram - wmark_low; | ||
65 | |||
66 | /* | ||
67 | * Not all the page cache can be freed, otherwise the system will | ||
68 | * start swapping. Assume at least half of the page cache, or the | ||
69 | * low watermark worth of cache, needs to stay. | ||
70 | */ | ||
71 | pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE]; | ||
72 | pagecache -= min(pagecache / 2, wmark_low); | ||
73 | available += pagecache; | ||
74 | |||
75 | /* | ||
76 | * Part of the reclaimable slab consists of items that are in use, | ||
77 | * and cannot be freed. Cap this estimate at the low watermark. | ||
78 | */ | ||
79 | available += global_page_state(NR_SLAB_RECLAIMABLE) - | ||
80 | min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low); | ||
81 | |||
82 | if (available < 0) | ||
83 | available = 0; | ||
84 | |||
50 | /* | 85 | /* |
51 | * Tagged format, for easy grepping and expansion. | 86 | * Tagged format, for easy grepping and expansion. |
52 | */ | 87 | */ |
53 | seq_printf(m, | 88 | seq_printf(m, |
54 | "MemTotal: %8lu kB\n" | 89 | "MemTotal: %8lu kB\n" |
55 | "MemFree: %8lu kB\n" | 90 | "MemFree: %8lu kB\n" |
91 | "MemAvailable: %8lu kB\n" | ||
56 | "Buffers: %8lu kB\n" | 92 | "Buffers: %8lu kB\n" |
57 | "Cached: %8lu kB\n" | 93 | "Cached: %8lu kB\n" |
58 | "SwapCached: %8lu kB\n" | 94 | "SwapCached: %8lu kB\n" |
@@ -105,6 +141,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
105 | , | 141 | , |
106 | K(i.totalram), | 142 | K(i.totalram), |
107 | K(i.freeram), | 143 | K(i.freeram), |
144 | K(available), | ||
108 | K(i.bufferram), | 145 | K(i.bufferram), |
109 | K(cached), | 146 | K(cached), |
110 | K(total_swapcache_pages()), | 147 | K(total_swapcache_pages()), |
@@ -183,4 +220,4 @@ static int __init proc_meminfo_init(void) | |||
183 | proc_create("meminfo", 0, NULL, &meminfo_proc_fops); | 220 | proc_create("meminfo", 0, NULL, &meminfo_proc_fops); |
184 | return 0; | 221 | return 0; |
185 | } | 222 | } |
186 | module_init(proc_meminfo_init); | 223 | fs_initcall(proc_meminfo_init); |
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c index 5f9bc8a746c9..d4a35746cab9 100644 --- a/fs/proc/nommu.c +++ b/fs/proc/nommu.c | |||
@@ -131,4 +131,4 @@ static int __init proc_nommu_init(void) | |||
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
133 | 133 | ||
134 | module_init(proc_nommu_init); | 134 | fs_initcall(proc_nommu_init); |
diff --git a/fs/proc/page.c b/fs/proc/page.c index b8730d9ebaee..e647c55275d9 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -118,10 +118,11 @@ u64 stable_page_flags(struct page *page) | |||
118 | /* | 118 | /* |
119 | * PageTransCompound can be true for non-huge compound pages (slab | 119 | * PageTransCompound can be true for non-huge compound pages (slab |
120 | * pages or pages allocated by drivers with __GFP_COMP) because it | 120 | * pages or pages allocated by drivers with __GFP_COMP) because it |
121 | * just checks PG_head/PG_tail, so we need to check PageLRU to make | 121 | * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon |
122 | * sure a given page is a thp, not a non-huge compound page. | 122 | * to make sure a given page is a thp, not a non-huge compound page. |
123 | */ | 123 | */ |
124 | else if (PageTransCompound(page) && PageLRU(compound_trans_head(page))) | 124 | else if (PageTransCompound(page) && (PageLRU(compound_head(page)) || |
125 | PageAnon(compound_head(page)))) | ||
125 | u |= 1 << KPF_THP; | 126 | u |= 1 << KPF_THP; |
126 | 127 | ||
127 | /* | 128 | /* |
@@ -217,4 +218,4 @@ static int __init proc_page_init(void) | |||
217 | proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); | 218 | proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); |
218 | return 0; | 219 | return 0; |
219 | } | 220 | } |
220 | module_init(proc_page_init); | 221 | fs_initcall(proc_page_init); |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c deleted file mode 100644 index 70779b2fc209..000000000000 --- a/fs/proc/proc_devtree.c +++ /dev/null | |||
@@ -1,240 +0,0 @@ | |||
1 | /* | ||
2 | * proc_devtree.c - handles /proc/device-tree | ||
3 | * | ||
4 | * Copyright 1997 Paul Mackerras | ||
5 | */ | ||
6 | #include <linux/errno.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/time.h> | ||
9 | #include <linux/proc_fs.h> | ||
10 | #include <linux/seq_file.h> | ||
11 | #include <linux/printk.h> | ||
12 | #include <linux/stat.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/export.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <asm/uaccess.h> | ||
18 | #include "internal.h" | ||
19 | |||
20 | static inline void set_node_proc_entry(struct device_node *np, | ||
21 | struct proc_dir_entry *de) | ||
22 | { | ||
23 | np->pde = de; | ||
24 | } | ||
25 | |||
26 | static struct proc_dir_entry *proc_device_tree; | ||
27 | |||
28 | /* | ||
29 | * Supply data on a read from /proc/device-tree/node/property. | ||
30 | */ | ||
31 | static int property_proc_show(struct seq_file *m, void *v) | ||
32 | { | ||
33 | struct property *pp = m->private; | ||
34 | |||
35 | seq_write(m, pp->value, pp->length); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int property_proc_open(struct inode *inode, struct file *file) | ||
40 | { | ||
41 | return single_open(file, property_proc_show, __PDE_DATA(inode)); | ||
42 | } | ||
43 | |||
44 | static const struct file_operations property_proc_fops = { | ||
45 | .owner = THIS_MODULE, | ||
46 | .open = property_proc_open, | ||
47 | .read = seq_read, | ||
48 | .llseek = seq_lseek, | ||
49 | .release = single_release, | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * For a node with a name like "gc@10", we make symlinks called "gc" | ||
54 | * and "@10" to it. | ||
55 | */ | ||
56 | |||
57 | /* | ||
58 | * Add a property to a node | ||
59 | */ | ||
60 | static struct proc_dir_entry * | ||
61 | __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp, | ||
62 | const char *name) | ||
63 | { | ||
64 | struct proc_dir_entry *ent; | ||
65 | |||
66 | /* | ||
67 | * Unfortunately proc_register puts each new entry | ||
68 | * at the beginning of the list. So we rearrange them. | ||
69 | */ | ||
70 | ent = proc_create_data(name, | ||
71 | strncmp(name, "security-", 9) ? S_IRUGO : S_IRUSR, | ||
72 | de, &property_proc_fops, pp); | ||
73 | if (ent == NULL) | ||
74 | return NULL; | ||
75 | |||
76 | if (!strncmp(name, "security-", 9)) | ||
77 | ent->size = 0; /* don't leak number of password chars */ | ||
78 | else | ||
79 | ent->size = pp->length; | ||
80 | |||
81 | return ent; | ||
82 | } | ||
83 | |||
84 | |||
85 | void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop) | ||
86 | { | ||
87 | __proc_device_tree_add_prop(pde, prop, prop->name); | ||
88 | } | ||
89 | |||
90 | void proc_device_tree_remove_prop(struct proc_dir_entry *pde, | ||
91 | struct property *prop) | ||
92 | { | ||
93 | remove_proc_entry(prop->name, pde); | ||
94 | } | ||
95 | |||
96 | void proc_device_tree_update_prop(struct proc_dir_entry *pde, | ||
97 | struct property *newprop, | ||
98 | struct property *oldprop) | ||
99 | { | ||
100 | struct proc_dir_entry *ent; | ||
101 | |||
102 | if (!oldprop) { | ||
103 | proc_device_tree_add_prop(pde, newprop); | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | for (ent = pde->subdir; ent != NULL; ent = ent->next) | ||
108 | if (ent->data == oldprop) | ||
109 | break; | ||
110 | if (ent == NULL) { | ||
111 | pr_warn("device-tree: property \"%s\" does not exist\n", | ||
112 | oldprop->name); | ||
113 | } else { | ||
114 | ent->data = newprop; | ||
115 | ent->size = newprop->length; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Various dodgy firmware might give us nodes and/or properties with | ||
121 | * conflicting names. That's generally ok, except for exporting via /proc, | ||
122 | * so munge names here to ensure they're unique. | ||
123 | */ | ||
124 | |||
125 | static int duplicate_name(struct proc_dir_entry *de, const char *name) | ||
126 | { | ||
127 | struct proc_dir_entry *ent; | ||
128 | int found = 0; | ||
129 | |||
130 | spin_lock(&proc_subdir_lock); | ||
131 | |||
132 | for (ent = de->subdir; ent != NULL; ent = ent->next) { | ||
133 | if (strcmp(ent->name, name) == 0) { | ||
134 | found = 1; | ||
135 | break; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | spin_unlock(&proc_subdir_lock); | ||
140 | |||
141 | return found; | ||
142 | } | ||
143 | |||
144 | static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de, | ||
145 | const char *name) | ||
146 | { | ||
147 | char *fixed_name; | ||
148 | int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */ | ||
149 | int i = 1, size; | ||
150 | |||
151 | realloc: | ||
152 | fixed_name = kmalloc(fixup_len, GFP_KERNEL); | ||
153 | if (fixed_name == NULL) { | ||
154 | pr_err("device-tree: Out of memory trying to fixup " | ||
155 | "name \"%s\"\n", name); | ||
156 | return name; | ||
157 | } | ||
158 | |||
159 | retry: | ||
160 | size = snprintf(fixed_name, fixup_len, "%s#%d", name, i); | ||
161 | size++; /* account for NULL */ | ||
162 | |||
163 | if (size > fixup_len) { | ||
164 | /* We ran out of space, free and reallocate. */ | ||
165 | kfree(fixed_name); | ||
166 | fixup_len = size; | ||
167 | goto realloc; | ||
168 | } | ||
169 | |||
170 | if (duplicate_name(de, fixed_name)) { | ||
171 | /* Multiple duplicates. Retry with a different offset. */ | ||
172 | i++; | ||
173 | goto retry; | ||
174 | } | ||
175 | |||
176 | pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n", | ||
177 | np->full_name, fixed_name); | ||
178 | |||
179 | return fixed_name; | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * Process a node, adding entries for its children and its properties. | ||
184 | */ | ||
185 | void proc_device_tree_add_node(struct device_node *np, | ||
186 | struct proc_dir_entry *de) | ||
187 | { | ||
188 | struct property *pp; | ||
189 | struct proc_dir_entry *ent; | ||
190 | struct device_node *child; | ||
191 | const char *p; | ||
192 | |||
193 | set_node_proc_entry(np, de); | ||
194 | for (child = NULL; (child = of_get_next_child(np, child));) { | ||
195 | /* Use everything after the last slash, or the full name */ | ||
196 | p = kbasename(child->full_name); | ||
197 | |||
198 | if (duplicate_name(de, p)) | ||
199 | p = fixup_name(np, de, p); | ||
200 | |||
201 | ent = proc_mkdir(p, de); | ||
202 | if (ent == NULL) | ||
203 | break; | ||
204 | proc_device_tree_add_node(child, ent); | ||
205 | } | ||
206 | of_node_put(child); | ||
207 | |||
208 | for (pp = np->properties; pp != NULL; pp = pp->next) { | ||
209 | p = pp->name; | ||
210 | |||
211 | if (strchr(p, '/')) | ||
212 | continue; | ||
213 | |||
214 | if (duplicate_name(de, p)) | ||
215 | p = fixup_name(np, de, p); | ||
216 | |||
217 | ent = __proc_device_tree_add_prop(de, pp, p); | ||
218 | if (ent == NULL) | ||
219 | break; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Called on initialization to set up the /proc/device-tree subtree | ||
225 | */ | ||
226 | void __init proc_device_tree_init(void) | ||
227 | { | ||
228 | struct device_node *root; | ||
229 | |||
230 | proc_device_tree = proc_mkdir("device-tree", NULL); | ||
231 | if (proc_device_tree == NULL) | ||
232 | return; | ||
233 | root = of_find_node_by_path("/"); | ||
234 | if (root == NULL) { | ||
235 | pr_debug("/proc/device-tree: can't find root\n"); | ||
236 | return; | ||
237 | } | ||
238 | proc_device_tree_add_node(root, proc_device_tree); | ||
239 | of_node_put(root); | ||
240 | } | ||
diff --git a/fs/proc/root.c b/fs/proc/root.c index 87dbcbef7fe4..5dbadecb234d 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -92,6 +92,8 @@ static int proc_parse_options(char *options, struct pid_namespace *pid) | |||
92 | int proc_remount(struct super_block *sb, int *flags, char *data) | 92 | int proc_remount(struct super_block *sb, int *flags, char *data) |
93 | { | 93 | { |
94 | struct pid_namespace *pid = sb->s_fs_info; | 94 | struct pid_namespace *pid = sb->s_fs_info; |
95 | |||
96 | sync_filesystem(sb); | ||
95 | return !proc_parse_options(data, pid); | 97 | return !proc_parse_options(data, pid); |
96 | } | 98 | } |
97 | 99 | ||
@@ -183,9 +185,6 @@ void __init proc_root_init(void) | |||
183 | proc_mkdir("openprom", NULL); | 185 | proc_mkdir("openprom", NULL); |
184 | #endif | 186 | #endif |
185 | proc_tty_init(); | 187 | proc_tty_init(); |
186 | #ifdef CONFIG_PROC_DEVICETREE | ||
187 | proc_device_tree_init(); | ||
188 | #endif | ||
189 | proc_mkdir("bus", NULL); | 188 | proc_mkdir("bus", NULL); |
190 | proc_sys_init(); | 189 | proc_sys_init(); |
191 | } | 190 | } |
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c index 62604be9f58d..ad8a77f94beb 100644 --- a/fs/proc/softirqs.c +++ b/fs/proc/softirqs.c | |||
@@ -41,4 +41,4 @@ static int __init proc_softirqs_init(void) | |||
41 | proc_create("softirqs", 0, NULL, &proc_softirqs_operations); | 41 | proc_create("softirqs", 0, NULL, &proc_softirqs_operations); |
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | module_init(proc_softirqs_init); | 44 | fs_initcall(proc_softirqs_init); |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 1cf86c0e8689..9d231e9e5f0e 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/time.h> | 10 | #include <linux/time.h> |
11 | #include <linux/irqnr.h> | 11 | #include <linux/irqnr.h> |
12 | #include <asm/cputime.h> | 12 | #include <linux/cputime.h> |
13 | #include <linux/tick.h> | 13 | #include <linux/tick.h> |
14 | 14 | ||
15 | #ifndef arch_irq_stat_cpu | 15 | #ifndef arch_irq_stat_cpu |
@@ -221,4 +221,4 @@ static int __init proc_stat_init(void) | |||
221 | proc_create("stat", 0, NULL, &proc_stat_operations); | 221 | proc_create("stat", 0, NULL, &proc_stat_operations); |
222 | return 0; | 222 | return 0; |
223 | } | 223 | } |
224 | module_init(proc_stat_init); | 224 | fs_initcall(proc_stat_init); |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index fb52b548080d..442177b1119a 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <linux/mm.h> | 1 | #include <linux/mm.h> |
2 | #include <linux/vmacache.h> | ||
2 | #include <linux/hugetlb.h> | 3 | #include <linux/hugetlb.h> |
3 | #include <linux/huge_mm.h> | 4 | #include <linux/huge_mm.h> |
4 | #include <linux/mount.h> | 5 | #include <linux/mount.h> |
@@ -152,7 +153,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) | |||
152 | 153 | ||
153 | /* | 154 | /* |
154 | * We remember last_addr rather than next_addr to hit with | 155 | * We remember last_addr rather than next_addr to hit with |
155 | * mmap_cache most of the time. We have zero last_addr at | 156 | * vmacache most of the time. We have zero last_addr at |
156 | * the beginning and also after lseek. We will have -1 last_addr | 157 | * the beginning and also after lseek. We will have -1 last_addr |
157 | * after the end of the vmas. | 158 | * after the end of the vmas. |
158 | */ | 159 | */ |
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c index 061894625903..33de567c25af 100644 --- a/fs/proc/uptime.c +++ b/fs/proc/uptime.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <linux/seq_file.h> | 5 | #include <linux/seq_file.h> |
6 | #include <linux/time.h> | 6 | #include <linux/time.h> |
7 | #include <linux/kernel_stat.h> | 7 | #include <linux/kernel_stat.h> |
8 | #include <asm/cputime.h> | 8 | #include <linux/cputime.h> |
9 | 9 | ||
10 | static int uptime_proc_show(struct seq_file *m, void *v) | 10 | static int uptime_proc_show(struct seq_file *m, void *v) |
11 | { | 11 | { |
@@ -49,4 +49,4 @@ static int __init proc_uptime_init(void) | |||
49 | proc_create("uptime", 0, NULL, &uptime_proc_fops); | 49 | proc_create("uptime", 0, NULL, &uptime_proc_fops); |
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | module_init(proc_uptime_init); | 52 | fs_initcall(proc_uptime_init); |
diff --git a/fs/proc/version.c b/fs/proc/version.c index 76817a60678c..d2154eb6d78f 100644 --- a/fs/proc/version.c +++ b/fs/proc/version.c | |||
@@ -31,4 +31,4 @@ static int __init proc_version_init(void) | |||
31 | proc_create("version", 0, NULL, &version_proc_fops); | 31 | proc_create("version", 0, NULL, &version_proc_fops); |
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | module_init(proc_version_init); | 34 | fs_initcall(proc_version_init); |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 9100d6959886..6a8e785b29da 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -468,17 +468,23 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr) | |||
468 | return rc; | 468 | return rc; |
469 | } | 469 | } |
470 | nhdr_ptr = notes_section; | 470 | nhdr_ptr = notes_section; |
471 | while (real_sz < max_sz) { | 471 | while (nhdr_ptr->n_namesz != 0) { |
472 | if (nhdr_ptr->n_namesz == 0) | ||
473 | break; | ||
474 | sz = sizeof(Elf64_Nhdr) + | 472 | sz = sizeof(Elf64_Nhdr) + |
475 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 473 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
476 | ((nhdr_ptr->n_descsz + 3) & ~3); | 474 | ((nhdr_ptr->n_descsz + 3) & ~3); |
475 | if ((real_sz + sz) > max_sz) { | ||
476 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
477 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
478 | break; | ||
479 | } | ||
477 | real_sz += sz; | 480 | real_sz += sz; |
478 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); | 481 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); |
479 | } | 482 | } |
480 | kfree(notes_section); | 483 | kfree(notes_section); |
481 | phdr_ptr->p_memsz = real_sz; | 484 | phdr_ptr->p_memsz = real_sz; |
485 | if (real_sz == 0) { | ||
486 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
487 | } | ||
482 | } | 488 | } |
483 | 489 | ||
484 | return 0; | 490 | return 0; |
@@ -648,17 +654,23 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr) | |||
648 | return rc; | 654 | return rc; |
649 | } | 655 | } |
650 | nhdr_ptr = notes_section; | 656 | nhdr_ptr = notes_section; |
651 | while (real_sz < max_sz) { | 657 | while (nhdr_ptr->n_namesz != 0) { |
652 | if (nhdr_ptr->n_namesz == 0) | ||
653 | break; | ||
654 | sz = sizeof(Elf32_Nhdr) + | 658 | sz = sizeof(Elf32_Nhdr) + |
655 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 659 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
656 | ((nhdr_ptr->n_descsz + 3) & ~3); | 660 | ((nhdr_ptr->n_descsz + 3) & ~3); |
661 | if ((real_sz + sz) > max_sz) { | ||
662 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
663 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
664 | break; | ||
665 | } | ||
657 | real_sz += sz; | 666 | real_sz += sz; |
658 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); | 667 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); |
659 | } | 668 | } |
660 | kfree(notes_section); | 669 | kfree(notes_section); |
661 | phdr_ptr->p_memsz = real_sz; | 670 | phdr_ptr->p_memsz = real_sz; |
671 | if (real_sz == 0) { | ||
672 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
673 | } | ||
662 | } | 674 | } |
663 | 675 | ||
664 | return 0; | 676 | return 0; |
@@ -1082,7 +1094,7 @@ static int __init vmcore_init(void) | |||
1082 | proc_vmcore->size = vmcore_size; | 1094 | proc_vmcore->size = vmcore_size; |
1083 | return 0; | 1095 | return 0; |
1084 | } | 1096 | } |
1085 | module_init(vmcore_init) | 1097 | fs_initcall(vmcore_init); |
1086 | 1098 | ||
1087 | /* Cleanup function for vmcore module. */ | 1099 | /* Cleanup function for vmcore module. */ |
1088 | void vmcore_cleanup(void) | 1100 | void vmcore_cleanup(void) |
@@ -1104,4 +1116,3 @@ void vmcore_cleanup(void) | |||
1104 | } | 1116 | } |
1105 | free_elfcorebuf(); | 1117 | free_elfcorebuf(); |
1106 | } | 1118 | } |
1107 | EXPORT_SYMBOL_GPL(vmcore_cleanup); | ||